Is there ever a reason to use goto in modern .NET code?

前端 未结 19 1561
野性不改
野性不改 2020-12-08 14:19

I just found this code in reflector in the .NET base libraries...

    if (this._PasswordStrengthRegularExpression != null)
    {
        this._PasswordStreng         


        
相关标签:
19条回答
  • 2020-12-08 14:49

    You can use a GOTO to perform recursion with better performance. It's a lot harder to maintain, but if you need those extra cycles you may be willing to pay the maintenance burden.

    Here's a simple example, with results:

    class Program
    {
        // Calculate (20!) 1 million times using both methods.
        static void Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();
            Int64 result = 0;
            for (int i = 0; i < 1000000; i++)
                result += FactR(20);
            Console.WriteLine("Recursive Time: " + sw.ElapsedMilliseconds);
    
            sw = Stopwatch.StartNew();
            result = 0;
            for (int i = 0; i < 1000000; i++)
                result += FactG(20);
            Console.WriteLine("Goto Time: " + sw.ElapsedMilliseconds);
            Console.ReadLine();
        }
    
        // Recursive Factorial
        static Int64 FactR(Int64 i)
        {
            if (i <= 1)
                return 1;
            return i * FactR(i - 1);
        }
    
        // Recursive Factorial (using GOTO)
        static Int64 FactG(Int64 i)
        {
            Int64 result = 1;
    
        Loop:
            if (i <= 1)
                return result;
    
            result *= i;
            i--;
            goto Loop;
        }
    

    Here are the results I get on my machine:

     Recursive Time: 820
     Goto Time: 259
    
    0 讨论(0)
  • 2020-12-08 14:52

    Goto's are frequently useful when writing parsers and lexers.

    0 讨论(0)
  • 2020-12-08 14:52

    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.

    0 讨论(0)
  • 2020-12-08 14:53

    Its probably not in the source code, that's just how the disassembled code looks.

    0 讨论(0)
  • 2020-12-08 14:57

    As other's have shown the code you see in reflector is necessarily the code that is written in the Framework. The compiler and optimizers can change code around to something that functions in a similar manner as long as it does not change the actual work done by the code. It should also be stated that the compiler implements all branches and loops as goto's (branches in IL, or jumps in assembly.) When the release mode is ran and the compiler tries to optimizes code to the simplest form that is functionally the same as your source.

    I have an example on different looping techniques that are all compiled to 100% the same IL when you compile for release. See Other Answer

    (I can't find it right now but Eric Lippert posted an note on how the C# compiler processes code. One of the points he made is how all loops are changed to goto's.)

    That being said, I have no problem with goto. If there is a better looping structure, use it. But sometimes you need something slightly then what you can squeeze out of for, foreach, while, do/while but you don't wanted the added mess and pain that comes from method calls (why waste 5 plus lines to convert a nested for into recursive methods.)

    0 讨论(0)
  • 2020-12-08 14:59

    I have seen goto used to break out of nested loops:

    How can I break out of two nested for loops in Objective-C?

    I don't see anything wrong with using it that way.

    0 讨论(0)
提交回复
热议问题