2015-09-04 89 views
20

我认识到处理可空类型的正确方法是使用HasValue属性。但我想知道为什么下面的switch语句在null情况下而不是默认情况下中断。使用VS2015 C#4.0。另一台使用VS2010 C#4.0的计算机没有这个问题。打开可空布尔值:如果值为真,则为空

private void Testing() 
    { 
     bool? boolValue = true; 

     switch (boolValue) 
     { 
      case null: 
       break; //even though value is true, code runs here 

      default: 
       break; 
     } 
    } 

编辑:行为与任何Nullable如果仅case Nulldefault指定观察。

+0

我在VS2013上没有得到这个行为 –

+0

我猜你的符号是过时的,它不运行你认为正在运行的东西,或者编译器正在做一些奇怪的优化,并且把两个相等的块。也许在那里添加一些实际的代码,看看它有什么作用。 –

+0

我在2010年没有得到那种行为。 – thewisegod

回答

5

这不是答案,我只是分享由VS2013和VS2015生成的IL代码。

原始C#代码:

public void Testing() 
{ 
    bool? boolValue = true; 

    switch (boolValue) 
    { 

     case null: 

      Console.WriteLine("null"); 

      break; 

     default: 
      Console.WriteLine("default"); 

      break; 
    } 
} 

VS2013 IL(反编译):

public void Testing() 
{ 
    bool? boolValue = new bool?(true); 
    bool valueOrDefault = boolValue.GetValueOrDefault(); 
    if (boolValue.HasValue) 
    { 
     Console.WriteLine("default"); 
    } 
    else 
    { 
     Console.WriteLine("null"); 
    } 
} 

VS2015 IL(反编译):

public void Testing() 
{ 
    bool? flag = new bool?(true); 
    bool? flag2 = flag; 
    bool? flag3 = flag2; 
    if (flag3.HasValue) 
    { 
     bool valueOrDefault = flag3.GetValueOrDefault(); 
    } 
    Console.WriteLine("null"); 
} 
+0

对我来说只有一个变量'nullable2'。没有标志1,2,3。但它似乎默认的部分根本不编译。问题是所有可空类型 –

+0

也许它也取决于反编译器。我正在使用ILSpy –

+0

但是为什么它会在VS2015中使用vendettamit? – MikeG

13

这将是非常短的答案:你刚刚击中两周前报道的Roslyn bug #4701

里程碑设置为1.1,所以现在您需要在单独的if子句中解决此问题,同时等待下一次编译器更新。