Подтвердить что ты не робот

Переключатель С# 6 с нулевым длинным значением по умолчанию для реальных значений

У меня есть эта простая программа с переключателем на nullable 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";
    }
  }
}

После компиляции в VS 2013 я всегда получаю "1" в качестве вывода. После компиляции в VS 2015 я всегда получаю "default" как вывод.

Это происходит только в том случае, если аргумент Test() длинный (не int).

Я декомпилировал тогда il-код и (по-моему) отсутствует "conv.i8", перед тем как сравнивать значения через "beq.s" (компилятор 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

Может ли кто-нибудь подтвердить это?

Если я сменил switch-Statement на "switch (orderId.Value)", все работает отлично. Но я не уверен, сколько из этих утверждений существует в нашей базе кода.

4b9b3361