关于if语句:c#是否更好地使用开关或if / else比较枚举

c# is it better to use a switch or if/else when comparing an enum

本问题已经有最佳答案,请猛点这里访问。

我有一个具有4个值的枚举,我只是好奇,对于if/else语句使用它来检查值是什么,还是使用switch语句比较好。

当我说得更好的时候,我的意思是在性能方面,因为这两个方面的可读性都差不多。

谢谢


我认为在性能方面,如果只有4个值需要检查,您不会感觉到任何差异。我发现,switch case语句产生的IL代码比if else语句短。

例子:C码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
static void Main(string[] args)
        {
            var testEnumeration = SomeEnum.Val3;

            if (testEnumeration == SomeEnum.Val1)
                Console.WriteLine("1");
            else if (testEnumeration == SomeEnum.Val2)
                Console.WriteLine("2");
            else if (testEnumeration == SomeEnum.Val3)
                Console.WriteLine("3");
            else if (testEnumeration == SomeEnum.Val4)
                Console.WriteLine("4");

            switch (testEnumeration)
            {
                case SomeEnum.Val1:
                    { Console.WriteLine("1"); break;}
                case SomeEnum.Val2:
                    { Console.WriteLine("2"); break; }
                case SomeEnum.Val3:
                    { Console.WriteLine("3"); break; }
                case SomeEnum.Val4:
                    { Console.WriteLine("4"); break; }
            }

        }

生成以下IL代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
.method private hidebysig static void  Main(string[] args) cil managed
{
  .entrypoint
  // Code size       180 (0xb4)
  .maxstack  2
  .locals init ([0] valuetype ConsoleTest.Program/SomeEnum testEnumeration,
           [1] bool CS$4$0000,
           [2] valuetype ConsoleTest.Program/SomeEnum CS$4$0001)
  IL_0000:  nop
  IL_0001:  ldc.i4.2
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldc.i4.0
  IL_0005:  ceq
  IL_0007:  ldc.i4.0
  IL_0008:  ceq
  IL_000a:  stloc.1
  IL_000b:  ldloc.1
  IL_000c:  brtrue.s   IL_001b
  IL_000e:  ldstr     "1"
  IL_0013:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0018:  nop
  IL_0019:  br.s       IL_0061
  IL_001b:  ldloc.0
  IL_001c:  ldc.i4.1
  IL_001d:  ceq
  IL_001f:  ldc.i4.0
  IL_0020:  ceq
  IL_0022:  stloc.1
  IL_0023:  ldloc.1
  IL_0024:  brtrue.s   IL_0033
  IL_0026:  ldstr     "2"
  IL_002b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0030:  nop
  IL_0031:  br.s       IL_0061
  IL_0033:  ldloc.0
  IL_0034:  ldc.i4.2
  IL_0035:  ceq
  IL_0037:  ldc.i4.0
  IL_0038:  ceq
  IL_003a:  stloc.1
  IL_003b:  ldloc.1
  IL_003c:  brtrue.s   IL_004b
  IL_003e:  ldstr     "3"
  IL_0043:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0048:  nop
  IL_0049:  br.s       IL_0061
  IL_004b:  ldloc.0
  IL_004c:  ldc.i4.3
  IL_004d:  ceq
  IL_004f:  ldc.i4.0
  IL_0050:  ceq
  IL_0052:  stloc.1
  IL_0053:  ldloc.1
  IL_0054:  brtrue.s   IL_0061
  IL_0056:  ldstr     "4"
  IL_005b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0060:  nop
  IL_0061:  ldloc.0
  IL_0062:  stloc.2
  IL_0063:  ldloc.2
  IL_0064:  switch     (
                        IL_007b,
                        IL_0089,
                        IL_0097,
                        IL_00a5)
  IL_0079:  br.s       IL_00b3
  IL_007b:  nop
  IL_007c:  ldstr     "1"
  IL_0081:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0086:  nop
  IL_0087:  br.s       IL_00b3
  IL_0089:  nop
  IL_008a:  ldstr     "2"
  IL_008f:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0094:  nop
  IL_0095:  br.s       IL_00b3
  IL_0097:  nop
  IL_0098:  ldstr     "3"
  IL_009d:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_00a2:  nop
  IL_00a3:  br.s       IL_00b3
  IL_00a5:  nop
  IL_00a6:  ldstr     "4"
  IL_00ab:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_00b0:  nop
  IL_00b1:  br.s       IL_00b3
  IL_00b3:  ret
} // end of method Program::Main