views:

118

answers:

2

This is very strange, maybe someone can explain what's happening, or this is a bug (though I tend to think that this is probably just something intricate about C#).

The following code throws the error "Cannot implicitly convert type 'uint?' to 'uint'.":

public void Test(UInt32? p)
{ 
    UInt32 x = p;
}

However, this code works without error:

public void Test(UInt32? p)
{
    UInt32 x = p ?? 1;
}

Huh? Why does this work? Why would the coalesce operator cause implicit conversion of UInt32? (nullable) to UInt32 (non-nullable), while the first error message says that there is no implicit conversion between those types?

+11  A: 

Think of it this way.

Nullable<T> is a value type. Obviously, it can't really be null. Thus, the expression:

p == null

Is really syntactic sugar for this:

!p.HasValue

Similarly, the expression:

p ?? 1

Is syntactic sugar for:

p.HasValue ? p.Value : 1

From the preceding, it's clear that the expression p ?? 1 is actually evaluating to a uint, which is why the code works without a cast.

Dan Tao
Very well explained. Makes total sense.
Alex
A: 

The coalescing operator ?? works because C# compiler has explicit support for nullable types to be on the left hand side of the operator. As Dan Tao explained, it's clear that such expression will never throw an exception.

Looking at the available operators on Nullable<T> type, there are none that would make p ?? 1 any more legal than int val = p. It only works because it's a compiler feature.

Igor Zevaka