Here is a line-to-line analysis of your code.
null.ToString();
Here a method is called on a null reference. Of course exception would be thrown.
int? foo = null;
This creates a struct foo
of type Nullable<int>
on the stack, and has its HasValue
property to false.
foo.ToString();
This calls the ToString()
method of Nullable<T>
, which is overridden to return an empty string (""
).(In your question you said that returns 0
. This is not true.) Note that calling an overridden method directly on a value type does not cause boxing.
0 == foo
This works and returns false because 0
is converted into a Int32?
which contains a value, but foo
does not contain any value. See this answer about nullable type conversion about and documentation about lifted operators
null == foo;
Works and returns true
because null
is converted to Int32?
which does not contain any value. This equals foo
, which also doesn't contain any value.
null == 0
Works and returns false
because null
is converted to Int32?
and 0
is converted to Int32?
but the former contains no value.