Because its a reference conversion. As the name implies, in a reference conversion, the only thing that changes is the reference, AKA the variable pointing to the object.
The bits that make up the string literal "string"
don't change, the only thing you are doing in Object o = "string"
is creating a variable o
typed Object
that points to the the string
"string"
. The value stored in the variable o
is precisely the address in memory where that string
is:
Given:
var s = "Hello";
Any of these conversions are reference conversions:
object o = s; //creates a new reference typed object pointing to "Hello".
IComparable<string> e = s; //creates a new reference tpyed...
o.GetType()
and e.GetType()
will both return System.String
because o
and e
both point to exactly the same object: "Hello"
.
Now this isn't the only conversion that can happen. There are tons of conversions that are not reference conversions or identity preserving conversions. An example? All user defined conversions (implicit
or explicit
operator):
int i = 1;
double d = i;
d.GetType() //returns Double.
Why? Because i
and d
are two different objects, the bits that make up an integer and a double are completely different. The implicit cast from int
to double
is a user defined operator:
class Bar
{
public Bar(Foo f) { ... }
}
class Foo
{
public static implicit operator Bar(Foo f) => new Bar(f);
}
Now if you do:
var f = new Foo();
object o = f;
Bar b = f; //implicit user defined conversion from Foo to Bar
You will get the following outputs:
o.GetType() //Reference conversion: returns Foo
b.GetType() //User defined conversion: returns Bar
Do note that all reference conversions are provided by the compiler, you can't define a reference conversion as a user defined operator:
public static implicit operator Object(Foo f) { ... } //compile time error.
All that said, there is one special non identity preserving conversion where GetType()
will still return the type of the original object. Can you tell me which one it is?
Also, reference conversions involving value types are not possible, precisely because a value type variable's value is not a reference, it's the value type instance itself.