带输出参数的构造函数

今天我看到一个看起来非常可怕的剪辑,但不幸的是我不能简单地改变它,所以我想知道我是否可以以某种方式绕过它。 我有一个带有构造函数的类,该构造函数具有成功的输出参数。 但这对我来说真的很难看。 而现在,当我从这个课程中衍生出来时,我必须带着这个参数 – 如果我想要或不想。

class ClassA { ClassA(out bool success) {...} } class B: ClassA { // call the constructor from ClassA but without the out-param } 

所以我应该知道它的良好实践,或者不知道如何避免从ClassB中宣布out-param。

好吧,无论如何,那个类的设计都被打破了,所以让我们多打破它( 注意!我不推荐这种方法!):

 void Main() { } public class ClassA { public ClassA(out bool success) { success = true; } } public class B: ClassA { private static bool success; // call the constructor from ClassA but without the out-param public B() : base(out success) { } } 

除此之外,你可以得到的最接近的是制作工厂方法:

 public class B : ClassA { public static B Create() { bool success; var result = new B(out success); if (success) return result; // TODO: Dispose result? throw new StupidProgrammerException(); } } 

你可以这样做:

 class ClassA { protected ClassA(out bool success) { success = true; } } class B : ClassA { [ThreadStatic] static bool success; // static to use in base(out success) call public bool Success { get; private set; } public B() : base(out success) { Success = success; success = false; // reset value } } 

这很丑陋,但至少如果你愿意,你可以摆脱out参数。

虽然将refout参数传递给构造函数很难看,但有些类型的创建可用实例的尝试会产生副作用,并且在已经发生某些副作用后可能会失败。 如果无法构造有效对象,构造函数可以将信息传递给调用者的唯一方法是将其存储在threadstatic字段中,将其封装在抛出的exception中,将其存储或传递给传入的对象或委托,或将其写入ref / out参数。 其中,只有ref / out参数明确表明客户端代码应该使用的信息的存在。

refout参数的存在通常表明应该protected构造函数,并且外部代码应该通过工厂方法来确保如果抛出exception,则将适当地使用传递出的对象。 但是,对于合理支持inheritance的类,它必须至少提供一个在其外部可见的构造函数。 如果构造失败,那么构造函数使用outref参数可能是让类调用者知道需要清理什么东西的最不邪恶的方法。