简体   繁体   中英

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

Note: I am running the above pieces of code on the www.compileonline.com website, btw. Not sure if trying on the Visual Studio compiler would yield different results, but I do not have access to Visual Studio currently.

TIA.

Both code throws InvalidOperationException because

From Nullable<T>.Value property

The value of the current Nullable<T> object if the HasValue property is true . An exception is thrown if the HasValue property is false .

In your both case, HasValue property will be false. That's why both code throws InvalidOperationException .

EDIT : Okey okey.. Looks like www.compileonline.com website uses Mono 2.10.2.0 and first code gives just warning like;

main.cs(9,34): warning CS0472: The result of comparing value type int' with null is false'

I checked out Bug Fixes page but I couldn't find anything about this issue. Keep searching..

Looks like in Mono 2.10.2.0 even if HasValue is false, this code doesn't throw exception. It just gives warning.

From 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'

So in our case, looks like Mono 2.10.2.0 checks out x is int? but x.Value is int and it says like (instead throwing exception);

this is an int and it is a value type , it never be equal to null .

EDIT2 : hdv has a point I think. This seems related with Bug 12608 which is fixed in Mono 3.1.10 but I couldn't be sure about that.

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

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

Your second example ;

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

throws InvalidOperationException as we are expected.

Unhandled Exception: System.InvalidOperationException: Nullable object must have a value. at System.Nullable`1[System.Int32].get_Value () [0x00000] in :0 at Test.Main () [0x00000] in :0

Wait a second..

In first example , we said;

Looks like it doesn't check HasValue property..

How even possible it checks HasValue property in this time? I think this is a online compiler bug but still I couldn't check it on Mono 3.+ version..

EDIT4 : I send a message the guy who created this site from it's contact page and explian this situation.

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

main.cs(9,38): warning CS0472: The result of comparing value type int' with null is false'

Compilation succeeded - 1 warning(s)

Executing the program....

$mono demo.exe

False

warning CS0472 tell you that, it is a bug in the online/mono compiler they are using.

The compiler you use wrongly optimizes away the call to the property get accessor. 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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