accidentally at work I wrote the following line of code:
string x = (object) null;
// It was var x = (object)null and I changed from var to string instead of
// object x = null;
This gave me a compilation error similar to this: Can't cast source type object to target type string
Why? Isn't null
just a bunch of zeros pointing to "nowhere" memory address, no matter what the type is?
The question here is basically "why does the compiler not take into account the fact that it knows that the assigned value is a constant reference known to be null?"
The answer is: why should it? What's the compelling benefit of taking that information into account? You deliberately said "I want this expression to be treated as though it were of type object", and you can't assign a value of type object to a variable of type string. What's the benefit of allowing that in this case?
The code seems to me to be highly likely to be a bug; surely the compiler should be telling you about it rather than allowing it.
maybe
object x = (string) null;
that might work,, but why would you?because object can hold a string,, but a string cant hold an object
string is inherited from object,, not the other way around.
It needs to be assignable - even if it may seem it's "the same null" and it shouldn't matter, the compiler still upholds the type. One advantage of that is in resolving overloads:
You can assign null to any variable of reference type without casting anything:
That's all it is in a weakly-typed language like C or C++.
In C#, a reference's type is an integral part of its identity.
(string)null
is not the same thing as(object)null
because one is astring
and one is anobject
.Furthermore, in C#
null
doesn't really have a numeric equivalent. References in C# are not the same thing as pointers and, semantically speaking, they do not have an associated memory address.null
simply means that the reference does not point to an object, and anull
reference's internal representation is an implementation detail.The problem is not the casting of
null
, it's thatobject
isn't assignable tostring
. This works fineThe reason this works if you remove the cast (
string x = null
) is laid out in section 2.4.4.6 of the C# Language SpecificationThe moment you introduce a cast (
(object)null
) you no longer have a null literal. Instead you have a value of typeobject
. It's essentially no different than