I just found this code in reflector in the .NET base libraries...
if (this._PasswordStrengthRegularExpression != null)
{
this._PasswordStrengthRegularExpression = this._PasswordStrengthRegularExpression.Trim();
if (this._PasswordStrengthRegularExpression.Length == 0)
{
goto Label_016C;
}
try
{
new Regex(this._PasswordStrengthRegularExpression);
goto Label_016C;
}
catch (ArgumentException exception)
{
throw new ProviderException(exception.Message, exception);
}
}
this._PasswordStrengthRegularExpression = string.Empty;
Label_016C:
... //Other stuff
I've heard all of the "thou shalt not use goto on fear of exile to hell for eternity" spiel. I always held MS coders in fairly high regard and while I may not have agreed with all of their decisions, I always respected their reasoning.
So - is there a good reason for code like this that I'm missing? Was this code extract just put together by an inept developer? or is .NET reflector returning inaccurate code?
I'm hoping there is a good reason, and I'm just blindly missing it.
Thanks for everyone's input
I don't like that code.
I would prefer to store the Regex in the member, and validate it when setting it, avoiding all of the need for logic when reading it.
I'm not crazy about gotos, but to say that they're never valid is silly.
I used one once to fix a defect in a particularly messy piece of code. To refactor the code and test it would not have been practical given the time constraint.
Besides, haven't we all seen conditional constructs that were so poorly coded that they make gotos seem benign?
I have not seen a valid case for Goto in many, many lines of .NET code both written and reviewed.
In languages that do not support structured exception handling with a finally block (PASCAL - a grandfather of structured programming languages, as well as classic C come to mind), tactical use of a GOTO could lead to much easier to understand code when used to perform cleanup when execution terminated inside nested loops (as opposed to correctly setting multiple loop termination conditions). Even back in the day, I did not use goto personally for that reason (probably for fear of "exile to hell eternally").
Take a look at a state diagram. If you believe that the best code structure to use is the one that most directly and clearly expresses your intent, then every one of those state transitions should be coded as a goto.
This tends to break down in the real world, though. The first issue is that we often need to halt the machine, exit out to other code, and resume the machine later - meaning that every one of those transitions tends to be a change to state variable, used to identify the correct state in a switch/case statement. This is really just a way to hide and delay the goto - writing to a state variable isn't much different to writing to the program-counter register, really. It's just a way to implement "goto there - but not now, later".
There are cases, though, where a goto works well to express what is happening in some kind of state model - I'd guess that an example would be one of those diagnostic flowcharts that doctors sometimes use. If you implement one of those as a program without using gotos for transitions, then really you're just making life difficult for yourself by encrypting the intent of your code.
It's just that by far the most common cases aren't likely to be hand-written code. I've written code generators that generate goto statements for transitions in various kinds of state model (decision handling, regular grammar parsing, etc) but I don't remember the last time I used a goto in hand-written code.
This may not be the best example but it does show a case where
goto
can be very handy.There are several valid uses for goto in .NET (C# specifically):
Simulating Switch Statement Fall-through Semantics.
Those coming from a C++ background are used to writing switch statements which automatically fall-through from case to case unless explicitly terminated with break. For C#, only trivial (empty) cases fall-through.
For example, in C++
In this C++ code the output is:
Here is similar C# code:
As written, this will not compile. There are several compilation errors that look like this:
Adding goto statements make it work:
... the other useful goto use in C# is...
Infinite Loops and Unrolled Recursion
I won't got into detail here since it is less useful, but occasionally we write infinite loops using
while(true)
constructs that are explicitly terminated with abreak
or re-executed with acontinue
statement. This might happen when we are trying to simulate recursive method calls but don't have any control over the potential scope of the recursion.You can obviously refactor that into a
while(true)
loop or refactor it into a separate method, but also using a label and a goto statement works.This use of goto is more debatable, but still something worth keeping in your mind as an option in very rare circumstances.