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

C# 为什么这段代码不抛出异常?,c#,exception,C#,Exception,我希望下面的代码行抛出异常,因为我正在访问一个赋值为null的可空变量的Value属性。但是,当我执行以下操作时,我没有得到任何异常: int? x=null; Console.WriteLine(x.Value==null); 但当我这样做的时候: Console.WriteLine(x.Value); 我确实得到了一个例外,这是可以预料的 但是,访问x.Value的两种方式之间有什么区别呢?为什么在第一种情况下我没有得到异常?这两段代码都试图访问x.Value属性 注意:顺便说一句,我正

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

int? x=null;
Console.WriteLine(x.Value==null);
但当我这样做的时候:

Console.WriteLine(x.Value);
我确实得到了一个例外,这是可以预料的

但是,访问
x.Value
的两种方式之间有什么区别呢?为什么在第一种情况下我没有得到异常?这两段代码都试图访问x.Value属性

注意:顺便说一句,我正在网站上运行上述代码。不确定在Visual Studio编译器上尝试是否会产生不同的结果,但我目前没有访问Visual Studio的权限

TIA.

两个代码都会抛出,因为

如果
HasValue
属性为空,则当前
Nullable
对象的值 是
真的
如果HasValue属性为false,则引发异常

在这两种情况下,属性都是假的。这就是两个代码都抛出的原因

编辑:好的,好的。。看起来网站使用了Mono 2.10.2.0,第一个代码给出了类似的警告

cs(9,34):警告CS0472:比较值类型的结果 带null的
int'为
false'

我签出了页面,但找不到有关此问题的任何信息。继续搜索

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

表达式的结果始终为“value1”,因为类型为 “value2”永远不等于“value3”类型的“null”

所以在我们的例子中,看起来Mono 2.10.2.0检查出
x
int?
,但是
x.Value
int
,它说的是like(而不是抛出异常)

这是一个
int
并且是一个值类型,它永远不等于
null

EDIT2:我认为这是有道理的。这似乎与Mono 3.1.10中的固定版本有关,但我不能确定这一点

还是继续找

EDIT3:好的。。我试过这些代码,其中说它使用Mono 2.8作为C#编译器,结果令人惊讶

你的

它不会抛出任何异常,甚至不会显示任何警告。它工作正常,结果生成
False
。看起来它没有检查
HasValue
属性,甚至没有检查
Nullable
(在本例中是
int
)的根是否为值类型

你的

按照我们的预期抛出InvalidOperationException

未处理的异常:System.InvalidOperationException:可为空的对象 必须有一个值。位于System.Nullable`1[System.Int32]。获取_值() [0x00000]in:0位于Test.Main()[0x00000]in :0

等一下。。 我们说,

看起来它没有检查属性

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

EDIT4:我向创建此网站的人发送了一条消息,并解释了这种情况。

使用you point时,mono编译器会重写/优化您的代码:

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>&1

cs(9,38):警告CS0472:将值类型
int'与null进行比较的结果是
false'

编译成功-1个警告

正在执行程序

$mono demo.exe

假的


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

错误使用的编译器优化了对属性
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编译器中的警告文本。

控制台中的WriteLine(x.Value==null);还引发无效的operationexception。两者都引发异常。compileonline.com使用Mono编译器,而不是Microsoft的。我认为您可能在该编译器中发现了一个bug。看起来您在联机编译器中发现了一个bug。我得到:警告为错误:表达式的结果总是“false”,因为“int”类型的值永远不等于“int”类型的“null”,所以可能是一个优化。问题是第一个代码不会引发异常,并问为什么。这是如何回答这个问题的呢?这可能是Mono 3.1.1(根据其发行说明)中修复的不同表现形式。我没有在这里安装Mono来检查它。@hvd-Hmm,是的,这可能与这个bug有关。我也没有单核细胞增多症,所以我不能检查。我补充道。谢谢。@Barmar现在呢?-1因为警告没有告诉您,
x.Value
没有得到计算,警告只告诉您与
null
的比较将永远不会返回
true
。如果编译器没有重写代码,它将在运行时出现异常而失败,但是,它在运行时不会失败。使用的mono编译器有一个错误,Microsoft编译器将给您一个不同的结果。警告说代码检索
x.Value
,丢弃它,并打印
false
。实际行为是打印
false
,而不检索
x.Value
。所以,不,警告仍然没有告诉你。@peer:谢谢你指出mono编译器重写的事实。编译器不检查是否存在可能的错误,这似乎是错误行为
using System.IO;
using System;

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

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

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