Note that there are some explanatory texts on larger screens.

plurals
  1. POconvincing C# compiler that execution will stop after a member returns
    text
    copied!<p>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:</p> <pre><code>MyClass instance; try { instance = getValue(); } catch (MyException ex) { Assert.Fail("Caught MyException"); } instance.doStuff(); // Use of unassigned local variable 'instance' </code></pre> <p>To make this code compile, I have to assign a value to <code>instance</code> either at its declaration or in the <code>catch</code> block. I could alternatively <code>return</code> after the <code>Assert.Fail</code> but that's still a workaround instead of the compiler just <em>knowing</em> that execution cannot continue after this point. <code>Assert.Fail</code> will never, to the best of my knowledge, allow execution to proceed past it, hence <code>instance</code> will never be used without a value. Why is it then that I must assign a value to it? If I change the <code>Assert.Fail</code> to something like <code>throw ex</code>, the code compiles fine, I assume because it knows that exception will disallow execution to proceed to a point where <code>instance</code> would be used uninitialized.</p> <p>Contrariwise, what if I didn't want the test to fail, but rather be marked as inconclusive? I could do an <code>Assert.Inconclusive</code> instead of <code>Fail</code>, and it would be nice if the compiler knew execution would not continue after that.</p> <p>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 <code>Assert.Fail</code>, 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?</p> <p><strong>Outside Unit Tests</strong></p> <p>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:</p> <pre><code>MyClass instance; if (badThings) { someMethodThatWillNeverReturn(); } else { instance = new MyClass(); } instance.doStuff(); </code></pre> <p>Here potentially I could replace the call to <code>someMethodThatWillNeverReturn</code> with throwing an exception, and perhaps if I had stuff to do, I could do it in the constructor for the exception.</p> <p><strong>Resharper Knows</strong></p> <p>If I add a <code>return</code> after <code>Assert.Fail</code> or <code>Assert.Inconclusive</code>, Resharper colors <code>return</code> gray and has a tooltip saying "Code is heuristically unreachable."</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload