[英]Why does this code not throw an exception?
I expected the following lines of code to throw an exception since I am accessing the Value
property of a nullable variable that is assigned a value of null
. 我期望以下几行代码抛出一个异常,因为我正在访问一个可
null
变量的Value
属性,该变量被赋值为null
。 However, I do not get any exception when I execute the below: 但是,当我执行以下操作时,我没有任何异常:
int? x=null;
Console.WriteLine(x.Value==null);
But when I do: 但当我这样做时:
Console.WriteLine(x.Value);
I do get an exception, as could be expected. 我确实得到了一个例外,正如可以预料的那样。
But what is the difference between the 2 ways of accessing x.Value
? 但是访问
x.Value
的两种方式有什么区别? Why do I not get an exception in the first case? 为什么我在第一种情况下没有例外? Both pieces of code are after all trying to access the x.Value property.
毕竟两段代码都试图访问x.Value属性。
Note: I am running the above pieces of code on the www.compileonline.com website, btw. 注意:我在www.compileonline.com网站上运行上面的代码,顺便说一句。 Not sure if trying on the Visual Studio compiler would yield different results, but I do not have access to Visual Studio currently.
不确定尝试使用Visual Studio编译器会产生不同的结果,但我目前无法访问Visual Studio。
TIA. TIA。
Both code throws InvalidOperationException
because 这两个代码都抛出
InvalidOperationException
因为
From Nullable<T>.Value
property 来自
Nullable<T>.Value
属性
The value of the current
Nullable<T>
object if theHasValue
property istrue
.如果
HasValue
属性为true
则为当前Nullable<T>
对象的true
。 An exception is thrown if the HasValue property is false .如果HasValue属性为false,则抛出异常 。
In your both case, HasValue
property will be false. 在这两种情况下,
HasValue
属性都将为false。 That's why both code throws InvalidOperationException
. 这就是为什么两个代码都抛出
InvalidOperationException
。
EDIT : Okey okey.. Looks like www.compileonline.com website uses Mono 2.10.2.0 and first code gives just warning like; 编辑 :Okey okey ..看起来www.compileonline.com网站使用Mono 2.10.2.0并且第一个代码只给出警告;
main.cs(9,34): warning CS0472: The result of comparing value type
int' with null is
false'main.cs(9,34):警告CS0472:将值类型
int' with null is
进行比较的结果int' with null is
false
I checked out Bug Fixes page but I couldn't find anything about this issue. 我查看了Bug修复页面,但我找不到任何关于此问题的信息。 Keep searching..
不停寻找..
Looks like in Mono 2.10.2.0 even if HasValue
is false, this code doesn't throw exception. 看起来在Mono 2.10.2.0中,即使
HasValue
为false,此代码也不会抛出异常。 It just gives warning. 它只是发出警告。
From Compiler Warning (level 2) CS0472
来自
Compiler Warning (level 2) CS0472
The result of the expression is always 'value1' since a value of type 'value2' is never equal to 'null' of type 'value3'
表达式的结果始终为'value1',因为类型'value2'的值永远不会等于'value3'类型的'null'
So in our case, looks like Mono 2.10.2.0 checks out x
is int?
那么在我们的例子中,看起来像Mono 2.10.2.0检查出
x
是int?
but x.Value
is int
and it says like (instead throwing exception); 但是
x.Value
是int
,它表示喜欢(而不是抛出异常);
this is an
int
and it is a value type , it never be equal tonull
.这是一个
int
,它是一个值类型 ,它永远不会等于null
。
EDIT2 : hdv has a point I think. EDIT2 : hdv有一点我认为。 This seems related with Bug 12608 which is fixed in Mono 3.1.10 but I couldn't be sure about that.
这似乎与Bug 12608有关,它已在Mono 3.1.10中修复,但我无法确定。
Still keep searching.. 还在继续搜索..
EDIT3 : Ok.. I tried these code on Ideone
, and in sample page
it says it uses Mono 2.8 for C# compiler, and results are surprising .. EDIT3 :好的..我在
Ideone
上尝试了这些代码,在sample page
它说它使用Mono 2.8 for C#编译器,结果令人惊讶 ..
Your first example
; 你的
first example
;
int? x = null;
Console.WriteLine(x.Value == null);
it doesn't throw any exception and it doesn't even show any warning either . 它不会抛出任何异常, 它甚至都没有显示任何警告 。 It just works perfectly and generates
False
as a result. 它完美地运行并因此生成
False
。 Looks like it doesn't check HasValue
property and it doesn't even look the root of Nullable<T>
(which is int
in our case) is value type or not. 看起来它没有检查
HasValue
属性,它甚至看不到Nullable<T>
的根(在我们的例子中是int
)是值类型与否。
Your second example
; 你的
second example
;
int? x = null;
Console.WriteLine(x.Value);
throws InvalidOperationException
as we are expected. 按预期抛出
InvalidOperationException
。
Unhandled Exception: System.InvalidOperationException: Nullable object must have a value.
未处理的异常:System.InvalidOperationException:Nullable对象必须具有值。 at System.Nullable`1[System.Int32].get_Value () [0x00000] in :0 at Test.Main () [0x00000] in :0
在System.Nullable`1 [System.Int32] .get_Value()[0x00000] in:0,在Test.Main()[0x00000] in:0
In first example
, we said; 在
first example
,我们说;
Looks like it doesn't check
HasValue
property..看起来它没有检查
HasValue
属性..
How even possible it checks HasValue
property in this time? 怎么可能它在这个时候检查
HasValue
属性? I think this is a online compiler bug but still I couldn't check it on Mono 3.+ version.. 我认为这是一个在线编译器错误,但我仍然无法在Mono 3 +版本上检查它。
EDIT4 : I send a message the guy who created this site from it's contact page and explian this situation. 编辑4 :我发送一条消息,从它的联系页面创建这个网站,并探讨这种情况。
When using the website compile online you point out, the mono compile does a rewrite/optimalization of your code: 在线使用网站时,你指出,单声道编译会对代码进行重写/优化:
using System.IO;
using System;
class Program
{
static void Main()
{
int? x=null;
Console.WriteLine(x.Value==null); //-> Console.WriteLine(false);
}
}
Compiling the source code....
编译源代码....
$mcs main.cs -out:demo.exe 2>&1
$ mcs main.cs -out:demo.exe 2>&1
main.cs(9,38): warning CS0472: The result of comparing value type
int' with null is
false'main.cs(9,38):警告CS0472:将值类型
int' with null is
进行比较的结果int' with null is
falseCompilation succeeded - 1 warning(s)
编译成功 - 1个警告
Executing the program....
执行程序....
$mono demo.exe
$ mono demo.exe
False
假
warning CS0472 tell you that, it is a bug in the online/mono compiler they are using. 警告CS0472告诉您,这是他们正在使用的在线/单声道编译器中的错误。
The compiler you use wrongly optimizes away the call to the property get
accessor. 你错误地使用的编译器优化了对属性
get
访问器的调用。 This code reproduces the bug, with that compiler: 此代码使用该编译器重现该错误:
using System;
static class Program
{
static void Main()
{
Console.WriteLine(Prop == null);
}
static int Prop
{
get
{
throw new NotImplementedException("This error must be!");
}
}
}
The Visual C# compiler does not have this bug. Visual C#编译器没有此错误。 But it has bad warning texts in some cases.
但在某些情况下,它有严重的警告文字。 Try changing
int
to DateTime
, and ==
to >
in my code, and see warning text from Visual C# compiler. 尝试将
int
更改为DateTime
,并在我的代码中将==
更改为>
,并从Visual C#编译器中查看警告文本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.