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!");
}
}
}