带有输出参数的构造函数

时间:2013-10-28 11:13:43

标签: c# constructor out

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

class ClassA {
    ClassA(out bool success) {...}
}

class B: ClassA {
    // call the constructor from ClassA but without the out-param
}

所以,我应该知道它的良好做法,或者不知道如何避免从ClassB宣布外派。

3 个答案:

答案 0 :(得分:3)

您可以这样做:

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参数。

答案 1 :(得分:3)

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

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

答案 2 :(得分:1)

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

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();
    }
}