Consider the following code:
int? myInt = null;
var hasValue = myInt.HasValue;
This is perfectly acceptable, and HasValue
will return false. But how have I managed to reference a property on an object that is null? The following wouldn't work:
public class MyClass
{
public bool MyBool { get { return true; } };
}
// Elsewhere in code...
MyClass myObject = null;
myObject.MyBool;
This would raise a null reference exception. The fact I'm comparing the two code snippets above as though they are equal tells me that I'm misunderstanding a structure or some syntax somewhere.
Can somebody please tell me why code snippet 1 does not raise an exception, but why my code snippet 2 would?
In the first case, you have a value of type Nullable<int>
, which is "the null value for the type". The Nullable<T>
type is a value type with two fields, like this:
public struct Nullable<T> where T : struct
{
private T value;
private bool hasValue;
}
When you use the null
literal with a Nullable<T>
, you're really just creating a value where the value
field has the default value of T
, and hasValue
is false. Using the HasValue
property isn't following a reference - it's just getting a field out of the struct.
In the second case, the value of myObject
is a null reference... so if you try to use the MyBool
property, that fails because it's trying to find an object when there isn't one.
So the key points are:
Nullable<T>
is a struct, not a classNullable<T>
is just a value with two fields, not a referencenull
literal just means "the null value of the relevant type", it does not always mean a null reference.See more on this question at Stackoverflow