问题
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