Is there any significant difference between using if/else and switch-case in C#?

前端 未结 20 794
时光取名叫无心
时光取名叫无心 2020-11-22 07:25

What is the benefit/downside to using a switch statement vs. an if/else in C#. I can\'t imagine there being that big of a difference, other than m

相关标签:
20条回答
  • Interest question. This came up a few weeks ago at work and we found an answer by writing an example snippet and viewing it in .NET Reflector (reflector is awesome!! i love it).

    This is what we discovered: A valid switch statement for anything other than a string gets compiled to IL as a switch statement. However IF it is a string it is rewritten as a if/else if/else in IL. So in our case we wanted to know how switch statements compare strings e.g is case-sensitive etc. and reflector quickly gave us an answer. This was useful to know.

    If you want to do case-sensitive compare on strings then you could use a switch statement as it is faster than performing a String.Compare in an if/else. (Edit: Read What is quicker, switch on string or elseif on type? for some actual performance tests) However if you wanted to do a case-insensitive then it is better using a if/else as the resulting code is not pretty.

    switch (myString.ToLower())
    {
      // not a good solution
    }
    

    The best rule of thumb is to use switch statements if it makes sense (seriously), e.g:

    • it improves the readability of your code
    • you are comparing a range of values (float, int) or an enum

    If you need to manipulate the value to feed into the switch statement (create a temporary variable to switch against) then you probably should be using an if/else control statement.

    An update:

    It is actually better to convert the string to uppercase (e.g. ToUpper()) as that has been apparently there are further optimizations that the just-in-time compiler can do as when compared to the ToLower(). It is a micro optimization, however in a tight loop it could be useful.


    A little side note:

    To improve the readability of switch statements try the following:

    • put the most likely branch first i.e. most accessed
    • if they are all likely to occur, list them in alphabetical order so it is easier to find them.
    • never use the default catch-all for the last remaining condition, that's lazy and will cause issues later on in the code's life.
    • use the default catch-all to assert an unknown condition even though it highly unlikely it will ever occur. that is what asserts are good for.
    0 讨论(0)
  • 2020-11-22 07:27

    I didn't see anyone else raise the (obvious?) point that the supposed efficiency advantage of the switch statement is dependent on the various cases being approximately equally likely. In cases where one (or a few) of the values are much more likely, the if-then-else ladder can be much faster, by ensuring the most common cases are checked first:

    So, for example:

    if (x==0) then {
      // do one thing
    } else if (x==1) {
      // do the other thing
    } else if (x==2) {
      // do the third thing
    }
    

    vs

    switch(x) {
      case 0: 
             // do one thing
             break;
      case 1: 
             // do the other thing
             break;
      case 2: 
             // do the third thing
             break;
    }
    

    If x is zero 90% of the time, the "if-else" code can be twice as fast as the switch-based code. Even if the compiler turns the "switch" into some kind of clever table-driven goto, it still won't be as fast as simply checking for zero.

    0 讨论(0)
  • 2020-11-22 07:27

    If you are just using if or else statement the base solution is using the comparsion ? operator

    (value == value1) ? (type1)do this : (type1)or do this;
    

    You can do the or routine in a switch

    switch(typeCode)
    {
       case TypeCode:Int32:
       case TypeCode.Int64:
         //dosomething here
         break;
       default: return;
    }
    
    0 讨论(0)
  • 2020-11-22 07:27

    Something that I just noticed is that you can combine if/else and switch statements! Very useful when needing to check preconditions.

    if (string.IsNullOrEmpty(line))
    {
        //skip empty lines
    }
    else switch (line.Substring(0,1))
    {
        case "1":
            Console.WriteLine(line);
            break;
        case "9":
            Console.WriteLine(line);
            break;
        default:
            break;
    }
    
    0 讨论(0)
  • 2020-11-22 07:29

    Three reasons to prefer the switch:

    • A compiler targeting native code can often compile a switch statement into one conditional branch plus an indirect jump whereas a sequence of ifs requires a sequence of conditional branches. Depending on the density of cases a great many learned papers have been written about how to compile case statements efficiently; some are linked from the lcc compiler page. (Lcc had one of the more innovative compilers for switches.)

    • A switch statement is a choice among mutually exclusive alternatives and the switch syntax makes this control flow more transparent to the programmer then a nest of if-then-else statements.

    • In some languages, including definitely ML and Haskell, the compiler checks to see if you have left out any cases. I view this feature as one of the major advantages of ML and Haskell. I don't know if C# can do this.

    An anecdote: at a lecture he gave on receiving an award for lifetime achievement, I heard Tony Hoare say that of all the things he did in his career, there were three that he was most proud of:

    • Inventing Quicksort
    • Inventing the switch statement (which Tony called the case statement)
    • Starting and ending his career in industry

    I can't imagine living without switch.

    0 讨论(0)
  • 2020-11-22 07:29

    Side topic, but I often worry about (and more often see) if/else and switch statement get way too large with too many cases. These often hurt maintainability.

    Common culprits include:

    1. Doing too much inside of multiple if statements
    2. More case statements than humanly possible to analyze
    3. Too many conditions in the if evaluation to know what is being looked for

    To fix:

    1. Extract to Method refactoring.
    2. Use a Dictionary with method pointers instead of a case, or use an IoC for added configurability. Method factories also can be helpful.
    3. Extract the conditions to their own method
    0 讨论(0)
提交回复
热议问题