为什么这段代码不会抛出异常?

时间:2014-01-15 07:52:07

标签: c# exception

我期望以下几行代码抛出异常,因为我正在访问被赋值为Value的可为空变量的null属性。但是,当我执行以下操作时,我没有任何异常:

int? x=null;
Console.WriteLine(x.Value==null);

但是当我这样做时:

Console.WriteLine(x.Value);

我确实得到了一个例外,正如可以预料的那样。

但是访问x.Value的两种方式之间有什么区别?为什么我在第一种情况下没有例外?毕竟两段代码都试图访问x.Value属性。

注意:我在www.compileonline.com网站上运行上面的代码,顺便说一句。不确定尝试使用Visual Studio编译器会产生不同的结果,但我目前无法访问Visual Studio。

TIA。

3 个答案:

答案 0 :(得分:5)

两个代码都抛出InvalidOperationException,因为

来自Nullable<T>.Value property

  

Nullable<T>属性的当前HasValue对象的值   是true如果HasValue属性为false ,则抛出异常。

在这两种情况下,HasValue属性都将为false。这就是为什么两个代码都抛出InvalidOperationException

编辑:Okey okey ..看起来www.compileonline.com网站使用的是Mono 2.10.2.0,第一个代码只提供警告;

  

main.cs(9,34):警告CS0472:比较值类型的结果   int' with null is假“

我查看了Bug Fixes页面,但我找不到任何关于此问题的信息。继续搜索..

Mono 2.10.2.0 中看起来即使HasValue为false,此代码也不会引发异常。它只是发出警告。

来自Compiler Warning (level 2) CS0472

  

表达式的结果总是为'value1',因为type是值   'value2'永远不会等于'value3'类型的'null'

所以在我们的情况下,看起来像 Mono 2.10.2.0 检出xint?x.Valueint并且它说像(而不是抛出异常);

  

这是int,它是值类型,它永远不会等于null

EDIT2 hdv我认为有一点。这似乎与{em> Mono 3.1.10 中修复的Bug 12608有关,但我无法确定。

仍在继续搜索..

EDIT3 :好的..我在Ideone上尝试了这些代码,在sample page中它说它使用 Mono 2.8 进行C#编译,结果令人惊讶 ..

您的first example;

int? x = null;
Console.WriteLine(x.Value == null);

它不会抛出任何异常,它甚至不会显示任何警告。它完美地运行并因此生成False。看起来它没有检查HasValue属性,它甚至看不到Nullable<T>的根(在我们的例子中是int)是值类型或不。

您的second example;

int? x = null;
Console.WriteLine(x.Value);

按照我们的预期抛出InvalidOperationException

  

未处理的异常:System.InvalidOperationException:Nullable对象   必须有价值。在System.Nullable`1 [System.Int32] .get_Value()   [0x00000] in:0,在Test.Main()[0x00000]中   :0

等一下..

first example,我们说;

  

看起来它没有检查HasValue属性..

在这段时间内,它有多可能检查HasValue属性?我认为这是一个在线编译器错误,但我仍然无法在 Mono 3。+ 版本上检查它。

EDIT4 :我从 contact page 发送了一个创建此网站的人的消息,并探讨了这种情况。

答案 1 :(得分:5)

使用你指出的website compile online时,单声道编译会对代码进行重写/优化:

using System.IO;
using System;

class Program
{
    static void Main()
    {
        int? x=null;
        Console.WriteLine(x.Value==null);  //-> Console.WriteLine(false);    
    }
}

  

编译源代码....

     

$ mcs main.cs -out:demo.exe 2&gt;&amp; 1

     

main.cs(9,38):警告CS0472:比较值类型int' with null is false'的结果

     

编译成功 - 1个警告

     

执行程序......

     

$ mono demo.exe

     

警告CS0472告诉您,这是他们使用的在线/单声道编译器中的错误。

答案 2 :(得分:0)

您错误使用的编译器优化了对属性get访问器的调用。此代码使用该编译器重现该错误:

using System;

static class Program
{
    static void Main()
    {
        Console.WriteLine(Prop == null);
    }

    static int Prop
    { 
        get
        {
            throw new NotImplementedException("This error must be!"); 
        } 
    }
}

Visual C#编译器没有此错误。但在某些情况下,它有严重的警告文字。尝试在我的代码中将int更改为DateTime,将==更改为>,并查看来自Visual C#编译器的警告文本。