I don't think this is currently possible or if it's even a good idea, but it's something I was thinking about just now. I use MSTest for unit testing my C# project. In one of my tests, I do the following:
MyClass instance;
try
{
instance = getValue();
}
catch (MyException ex)
{
Assert.Fail("Caught MyException");
}
instance.doStuff(); // Use of unassigned local variable 'instance'
To make this code compile, I have to assign a value to instance
either at its declaration or in the catch
block. I could alternatively return
after the Assert.Fail
but that's still a workaround instead of the compiler just knowing that execution cannot continue after this point. Assert.Fail
will never, to the best of my knowledge, allow execution to proceed past it, hence instance
will never be used without a value. Why is it then that I must assign a value to it? If I change the Assert.Fail
to something like throw ex
, the code compiles fine, I assume because it knows that exception will disallow execution to proceed to a point where instance
would be used uninitialized.
Contrariwise, what if I didn't want the test to fail, but rather be marked as inconclusive? I could do an Assert.Inconclusive
instead of Fail
, and it would be nice if the compiler knew execution would not continue after that.
So is it a case of runtime versus compile-time knowledge about where execution will be allowed to proceed? Would it ever be reasonable for C# to have some way of saying that a member, in this case Assert.Fail
, will never allow execution after it returns? Maybe that could be in the form of a method attribute. Would this be useful or an unnecessary complexity for the compiler?
Outside Unit Tests
Since people are [validly] pointing out that this is a silly way to write a unit test, consider my question outside the realm of unit testing:
MyClass instance;
if (badThings)
{
someMethodThatWillNeverReturn();
}
else
{
instance = new MyClass();
}
instance.doStuff();
Here potentially I could replace the call to someMethodThatWillNeverReturn
with throwing an exception, and perhaps if I had stuff to do, I could do it in the constructor for the exception.
Resharper Knows
If I add a return
after Assert.Fail
or Assert.Inconclusive
, Resharper colors return
gray and has a tooltip saying "Code is heuristically unreachable."