C# - 为什么将类型转换为对象的工作方式是这样的?



我试图理解:

Object obj = "string";
var type = obj.GetType(); // returns System.String 

我知道这是一个成功的隐式转换,但我不明白为什么如果调用obj.GetType()它会返回System.String而不是System.Object

如果我想有一个字符串类型,我不会将"字符串"分配给Object类型。如果obj保持Object类型会更正确。谁能解释一下?

您有一个string文字,其类型为string。当你把它赋给obj变量时,它是一个objectstring文字被隐式转换为object,这是有效的,因为所有的类类型都隐式继承自object

所以你有一个objectobj引用的对象的基础类型仍然是string.通过将其转换为object,您只是在制作编译器将obj视为object,而不是string。因此,例如,不能使用obj调用在string类型上声明的方法。

obj.GetType()返回基础类型,而不是将对象转换为的类型。这就是为什么你变得string而不是object.

因为它是参考转换。顾名思义,在引用转换中,唯一更改的是引用,即指向对象的变量。

构成字符串文字"string"的位不会更改,您Object o = "string"唯一要做的就是创建一个指向string"string"o类型化Object变量。存储在变量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,因为oe都指向完全相同的对象:"Hello"

现在,这不是唯一可能发生的转换。有大量的转换不是参考转换或身份保留转换。一个例子?所有用户定义的转换(implicitexplicit运算符):

int i = 1;
double d = i;
d.GetType() //returns Double.

为什么?由于id是两个不同的对象,因此构成整数和双精度的位完全不同。从intdouble的隐式强制转换是用户定义的运算符:

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()仍将返回原始对象的类型。你能告诉我是哪一个吗?

此外,涉及值类型的引用转换是不可能的,正是因为值类型变量的值不是引用,而是值类型实例本身。

实际上,由于C#中的所有内容都继承自object,因此一切都对象。例如,string类型派生自对象(有关详细信息,请查看此内容:值类型继承自 System.Object...为什么?这意味着,每个字符串都是一个对象 - 因此可以隐式转换为对象。但是,它仍然是一个字符串 - 它只是被视为一个对象。

字符串实际上保留在其核心中仍然是字符串,即使您尝试将其转换为对象 - 这对于每个继承项都是相同的。例如,如果您有以下代码:

public class Class2 : Class1
{
}
public class Class1
{
}

并在其他地方执行以下代码(我使用了交互式)

((Class1)new Class2()).GetType()

结果你仍然会得到Class2

实际上,我认为不可能这样做 - 你总是可以假装它是另一种类型,我看不出有任何理由认为这是不够的。

最新更新