Something just occurred to me earlier today that has got me scratching my head.
Any variable of type Nullable<T> can be assigned to null. For instance:
int? i = null;
At first I couldn't see how this would be possible without somehow defining an implicit conversion from object to Nullable<T>:
public static implicit operator Nullable<T>(object box);
But the above operator clearly does not exist, as if it did then the following would also have to be legal, at least at compile-time (which it isn't):
int? i = new object();
Then I realized that perhaps the Nullable<T> type could define an implicit conversion to some arbitrary reference type that can never be instantiated, like this:
public abstract class DummyBox
{
private DummyBox()
{ }
}
public struct Nullable<T> where T : struct
{
public static implicit operator Nullable<T>(DummyBox box)
{
if (box == null)
{
return new Nullable<T>();
}
// This should never be possible, as a DummyBox cannot be instantiated.
throw new InvalidCastException();
}
}
However, this does not explain what occurred to me next: if the HasValue property is false for any Nullable<T> value, then that value will be boxed as null:
int? i = new int?();
object x = i; // Now x is null.
Furthermore, if HasValue is true, then the value will be boxed as a T rather than a T?:
int? i = 5;
object x = i; // Now x is a boxed int, NOT a boxed Nullable<int>.
But this seems to imply that there is a custom implicit conversion from Nullable&