Jan*_*ich 11 .net c# c#-6.0 visual-studio-2015
我有一个这个简单的程序,可以在一个可以为空的long上切换:
class Program
{
static void Main(string[] args)
{ Console.WriteLine(Test(1)); }
private static string Test(long? orderId)
{
switch (orderId)
{
case 1:
return "1";
default:
return "default";
}
}
}
Run Code Online (Sandbox Code Playgroud)
在VS 2013中编译之后,我总是得到"1"作为输出.在VS 2015中编译后,我总是将"默认"作为输出.
只有当Test()的参数是long(不是int)时才会发生.
我已经反编译然后il代码和(在我看来)在通过"beq.s"比较值之前缺少"conv.i8"(VS 2013编译器发出它):
.method private hidebysig static string
Test(valuetype [mscorlib]System.Nullable`1<int64> orderId) cil managed
{
// Code size 46 (0x2e)
.maxstack 2
.locals init ([0] valuetype [mscorlib]System.Nullable`1<int64> V_0,
[1] valuetype [mscorlib]System.Nullable`1<int64> V_1,
[2] int64 V_2,
[3] string V_3)
//000011: private static string Test(long? orderId)
//000012: {
IL_0000: nop
//000013: switch (orderId)
IL_0001: ldarg.0
IL_0002: stloc.1
//000014: {
//000015: case 1:
//000016: return "1";
//000017: default:
//000018: return "default";
//000019: }
//000020: }
//000021: }
//000022: }
IL_0003: ldloc.1
IL_0004: stloc.0
IL_0005: ldloca.s V_0
IL_0007: call instance bool valuetype [mscorlib]System.Nullable`1<int64>::get_HasValue()
IL_000c: brfalse.s IL_0024
IL_000e: ldloca.s V_0
IL_0010: call instance !0 valuetype [mscorlib]System.Nullable`1<int64>::GetValueOrDefault()
IL_0015: stloc.2
IL_0016: ldloc.2
IL_0017: ldc.i4.1
IL_JF17: conv.i8 // added by me
IL_0018: beq.s IL_001c
IL_001a: br.s IL_0024
//000016: return "1";
IL_001c: ldstr "1"
IL_0021: stloc.3
IL_0022: br.s IL_002c
//000017: default:
//000018: return "default";
IL_0024: ldstr "default"
IL_0029: stloc.3
IL_002a: br.s IL_002c
//000019: }
//000020: }
IL_002c: ldloc.3
IL_002d: ret
} // end of method Program::Test
Run Code Online (Sandbox Code Playgroud)
谁能证实这一点?
如果我将switch-Statement更改为"switch(orderId.Value)",一切正常.但我不确定我们的代码库中存在多少这些语句.