带输出参数的构造函数
今天我看到一个看起来非常可怕的剪辑,但不幸的是我不能简单地改变它,所以我想知道我是否可以以某种方式绕过它。 我有一个带有构造函数的类,该构造函数具有成功的输出参数。 但这对我来说真的很难看。 而现在,当我从这个课程中衍生出来时,我必须带着这个参数 – 如果我想要或不想。
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参数。
虽然将ref
或out
参数传递给构造函数很难看,但有些类型的创建可用实例的尝试会产生副作用,并且在已经发生某些副作用后可能会失败。 如果无法构造有效对象,构造函数可以将信息传递给调用者的唯一方法是将其存储在threadstatic
字段中,将其封装在抛出的exception中,将其存储或传递给传入的对象或委托,或将其写入ref
/ out
参数。 其中,只有ref
/ out
参数明确表明客户端代码应该使用的信息的存在。
ref
或out
参数的存在通常表明应该protected
构造函数,并且外部代码应该通过工厂方法来确保如果抛出exception,则将适当地使用传递出的对象。 但是,对于合理支持inheritance的类,它必须至少提供一个在其外部可见的构造函数。 如果构造失败,那么构造函数使用out
或ref
参数可能是让类调用者知道需要清理什么东西的最不邪恶的方法。