Constructor with output-parameter

点点圈 提交于 2020-01-14 05:26:41

问题


today I saw a snipped that looked really horrible to me, but unfortunetly I cannot simply change it, so I wonder if I can bypass this somehow. I have a class with a constructor that has an output-parameter for success. But that looks really ugly to me. And now when deriving from this class I have to take this param with me- if I want to or not.

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

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

So I´d know if its good practise or if not how I can avoid declaring the out-param from ClassB.


回答1:


Well, the design of that class is broken anyway, so let's break it a bit more (NOTE! I do not recommend this approach!):

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)
    {
    }
}

Other than that, the closest you can get is making a factory method:

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



回答2:


You can do something like this:

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
    }
}

It's ugly, but at least you get rid of the out parameter if so you want.




回答3:


While passing ref or out parameters to a constructor is ugly, there are some types where attempts to create a usable instance will have side-effects, and might fail after some of those side-effects have already occurred. If it is not possible to construct a valid object, the only ways via which the constructor can pass information to the caller are by storing it in a threadstatic field, encapsulating it within the thrown exception, storing or feeding it to a passed-in object or delegate, or writing it to a ref/out parameter. Of those, only the ref/out parameter makes obvious the existence of information with which the client code should be doing something.

The existence of ref or out parameters is often an indication that a constructor should be protected, and that outside code should go through a factory methods which ensure that if an exception is thrown the passed-out object will get used suitably. For a class to reasonably support inheritance, however, it must offer at least one constructor which is visible outside it. Having that constructor use an out or ref parameter may be the least evil way for a class to let a caller know what things will need cleaning up if construction fails.



来源:https://stackoverflow.com/questions/19633251/constructor-with-output-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!