usaipavan
usaipavan

Reputation: 103

Confusion about Explicit operator implementation for Nullable<T> struct

I happened to go through the .net framework source code and happened to run across the explicit operator implementation for the Nullable struct implementation. The below screenshots show the implementation of Value property and also the implementation of explicit operator. I also understand that explicit operator is trying to convert from Nullable to T. My question is why is it not that the following code is not throwing an exception

Framework implementation

     public T Value {
        get {
            if (!HasValue) { 
                ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_NoValue); 
            }
            return value; 
        }
    }

 public static explicit operator T(Nullable<T> value) { 
        return value.Value; 
    }

Custome code

int? i = null;
int? i2 = (int?)i; //No Error

int? i = null;
int i2 = (int)i; //Runtime error

It says value.Value and ideally since HasValue will be false (since I assigned null) it should throw invalid operation exception but it happily assigns the value to i2. However instead of (int?)i if we change it to (int)i the InvalidOperatorException from Value property is being raised. My thought was when value.Value is called it will throw an exception because that property is being accessed and it will do its job.

Please clarify on the same

Thanks,

Sai Pavan

Upvotes: 3

Views: 252

Answers (4)

Marc Gravell
Marc Gravell

Reputation: 1062780

int? i2 = (int?)i;

Is just a straight copy operation from int? to int?. No conversion operators are involved. This is a flat copy of the memory contents of the struct variable.

Upvotes: 2

Steve Morgan
Steve Morgan

Reputation: 13091

You may be getting confused by the explicit operator.

It's not "explicit operator", it's "explicit operator T". In your case, that becomes "explicit operator int", because T is int.

explicit operator int is only called if you explicitly convert to an int (the clue's in the name ;-) ).

So, as has been said, i1 does not require conversion to int and the explicit operator int is not called.

Upvotes: 0

Richard Schneider
Richard Schneider

Reputation: 35477

In the case of int? i2 = (int?)i; //No Error, the explicit operator method is never being called on i because your are casting to int? not int.

Upvotes: 1

Felix K.
Felix K.

Reputation: 6281

Because you cast to int? and not to int

public static explicit operator T(Nullable<T> value) { 
    return value.Value; 
}

T is int but you are casting to int? so Value has never been called.

Upvotes: 2

Related Questions