C# – Why does the is operator return false when given null

c

It seems to me that the is operator is a bit inconsistent.

bool Test()
{
    // Returns false, but should return true.
    return null is string;
}

One expects that the null value belongs to any reference (or nullable) type. And indeed, the C# language specification says something which supports this hypothesis, for example (6.1.6 Implicit reference conversions):

The implicit reference conversions are:

• From the null literal to any reference-type.

The description (7.10.10 The is operator) of the is operator starts by saying that the expression (E is T) will result in true when a reference conversion from E to T exists, but then the authors go on by explicitly excluding the case when E is the null literal or has a null value.

Why do they do that? To me it seems counterintuitive.

Best Answer

This question was the subject of my blog on May 30th 2013. Thanks for the great question!


You're staring at an empty driveway.

Someone asks you "can your driveway hold a Honda Civic?"

Yes. Yes it can.

Someone points you at a second driveway. It is also empty. They ask "Can the current contents of my driveway fit in your driveway?"

Yes, obviously. Both driveways are empty! So clearly the contents of one can fit in the other, because there are no contents of either in the first place.

Someone asks you "Does your driveway contain a Honda Civic?"

No, it does not.

You're thinking that the is operator answers the second question: given this value, does it fit in a variable of that type? Does a null reference fit into a variable of this type? Yes it does.

That is not the question that the is operator answers. The question that the is operator answers is the third question. y is X does not ask "is y a legal value of a variable of type X?" It asks "Is y a valid reference to an object of type X?" Since a null reference is not a valid reference to any object of any type, the answer is "no". That driveway is empty; it doesn't contain a Honda Civic.

Another way to look at it is that y is X answers the question "if I said y as X, would I get a non-null result? If y is null, clearly the answer is no!


To look a little deeper at your question:

One expects that the null value belongs to any reference (or nullable) type

One would be implicitly assuming that a type is a set of values, and that assignment compatibility of a value y with a variable of type X is nothing more nor less than checking whether y is a member of set x.

Though that is an extremely common way of looking at types, that is not the only way of looking at types, and it is not the way that C# looks at types. Null references are members of no type in C#; assignment compatibility is not merely checking a set to see if it contains a value. Just because a null reference is assignment compatible with a variable of reference type X does not mean that null is a member of type X. The "is assignment compatible with" relation and the "is a member of type" relation obviously have a lot of overlap, but they are not identical in the CLR.

If musings about type theory interest you, check out my recent articles on the subject:

What is this thing you call a "type"? Part one

What is this thing you call a "type"? Part Two