简体   繁体   English

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

[英]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 the HasValue property is true . 如果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检查出xint? but x.Value is int and it says like (instead throwing exception); 但是x.Valueint ,它表示喜欢(而不是抛出异常);

this is an int and it is a value type , it never be equal to null . 这是一个int ,它是一个值类型 ,它永远不会等于null

EDIT2 : hdv has a point I think. EDIT2hdv有一点我认为。 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

Wait a second.. 等一会儿..

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 false

Compilation 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM