因为它是一个引用转换。顾名思义,在引用转换中,唯一改变的是reference,也就是指向对象的变量。
组成字符串文字"string"的位不会改变,你在Object o = "string"中做的唯一事情就是创建一个变量o键入Object,点到string"string"。存储在变量o 中的值正是string 所在的内存地址:
给定:
var s = "Hello";
任何这些转化都是参考转化:
object o = s; //creates a new reference typed object pointing to "Hello".
IComparable<string> e = s; //creates a new reference tpyed...
o.GetType() 和 e.GetType() 都将返回 System.String,因为 o 和 e 都指向完全相同的对象:"Hello"。
现在这不是唯一可能发生的转换。有大量的转换不是参考转换或身份保留转换。一个例子?所有用户定义的转换(implicit 或 explicit 运算符):
int i = 1;
double d = i;
d.GetType() //returns Double.
为什么?因为i 和d 是两个不同的对象,所以构成整数和双精度的位是完全不同的。从int 到double 的隐式转换是用户定义的运算符:
class Bar
{
public Bar(Foo f) { ... }
}
class Foo
{
public static implicit operator Bar(Foo f) => new Bar(f);
}
现在如果你这样做:
var f = new Foo();
object o = f;
Bar b = f; //implicit user defined conversion from Foo to Bar
您将获得以下输出:
o.GetType() //Reference conversion: returns Foo
b.GetType() //User defined conversion: returns Bar
请注意,所有引用转换都是由编译器提供的,您不能将引用转换定义为用户定义的运算符:
public static implicit operator Object(Foo f) { ... } //compile time error.
话虽如此,有一种特殊的非身份保留转换,GetType() 仍将返回原始对象的类型。你能告诉我是哪一个吗?
此外,涉及值类型的引用转换是不可能的,正是因为值类型变量的值不是引用,而是值类型实例本身。