string s = "hello world";
int i;
switch (s[1]) { //What is the second letter?
case 'h': i = 1; break;
case 'e': i = 2; break;
case 'l': i = 3; break;
case 'o': i = 4; break;
default: i = 5; break;
}
switch (i) {
case 1: s = "h"; break;
case 2: s = "e"; break;
case 3: s = "l"; break;
case 4: s = "o"; break;
default: s = string.Empty; break;
}
IL_0008: callvirt instance char [mscorlib]System.String::get_Chars(int32)
IL_000d: stloc.2
IL_000e: ldloc.2
IL_000f: ldc.i4.s 104
IL_0011: bgt.s IL_001f ;greater than 'h'? (special conditional)
IL_0013: ldloc.2
IL_0014: ldc.i4.s 101
IL_0016: beq.s IL_002f ;conditional branch (e)
IL_0018: ldloc.2
IL_0019: ldc.i4.s 104
IL_001b: beq.s IL_002b ;conditional branch (h)
IL_001d: br.s IL_003b
IL_001f: ldloc.2
IL_0020: ldc.i4.s 108
IL_0022: beq.s IL_0033 ;conditional branch (l)
IL_0024: ldloc.2
IL_0025: ldc.i4.s 111
IL_0027: beq.s IL_0037 ;conditional branch (o)
IL_0029: br.s IL_003b
IL_002b: ldc.i4.1 ;case 'h'
IL_002c: stloc.1
IL_002d: br.s IL_003d
IL_002f: ldc.i4.2 ;case 'e'
IL_0030: stloc.1
IL_0031: br.s IL_003d
IL_0033: ldc.i4.3 ;case 'l'
IL_0034: stloc.1
IL_0035: br.s IL_003d
IL_0037: ldc.i4.4 ;case 'o'
IL_0038: stloc.1
IL_0039: br.s IL_003d
IL_003b: ldc.i4.5 ;default
IL_003c: stloc.1
IL_0042: switch (
IL_0059,
IL_0061,
IL_0069,
IL_0071) ;single branching instruction
IL_0057: br.s IL_0079
IL_0059: ldstr "h" ;case 1
IL_005e: stloc.0
IL_005f: br.s IL_007f
IL_0061: ldstr "e" ;case 2
IL_0066: stloc.0
IL_0067: br.s IL_007f
IL_0069: ldstr "l" ;case 3
IL_006e: stloc.0
IL_006f: br.s IL_007f
IL_0071: ldstr "o" ;case 4
IL_0076: stloc.0
IL_0077: br.s IL_007f
IL_0079: ldsfld string [mscorlib]System.String::Empty ;default
IL_007e: stloc.0
IL_008b: ldstr "foo"
IL_0090: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_0095: brtrue.s IL_00c3
IL_0097: ldloc.s CS$0$0002
IL_0099: ldstr "bar"
IL_009e: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_00a3: brtrue.s IL_00ca
IL_00a5: ldloc.s CS$0$0002
IL_00a7: ldstr "pin"
IL_00ac: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_00b1: brtrue.s IL_00d1
IL_00b3: ldloc.s CS$0$0002
IL_00b5: ldstr "pop"
IL_00ba: call bool [mscorlib]System.String::op_Equality(string,
string)
IL_00bf: brtrue.s IL_00d8
I believe the compiler has a little flexibility.
I was under the impression that string-based select cases used a hashtable. The best way to find out, though, would be to compile code and disassemble it with reflector.
IL_00ea: volatile.
IL_00ec: ldsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32> '<PrivateImplementationDetails>{F321BCDB-EE97-4BEC-9C3A-65BCE7603F07}'::'$$method0x6000005-1'
IL_00f1: ldloc.s CS$0$0002
IL_00f3: ldloca.s CS$0$0003
IL_00f5: call instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,int32>::TryGetValue(!0,
!1&)
IL_00fa: brfalse.s IL_014d ;no match - go to default
IL_00fc: ldloc.s CS$0$0003
IL_00fe: switch (
IL_011d,
IL_0125,
IL_012d,
IL_0135,
IL_013d,
IL_0145)