当你做GetType()时真的会发生什么?

我们知道,C#对象有一个指向其类型的指针,因此当您调用GetType()它会检查该指针并返回对象的实际类型。 但如果我这样做:

 A objA = new A(); object obj = (object)objA; if (obj.GetType() == typeof(object)) ; // this is true 

但是这里发生了什么object obj = (object)objA; ? 它是否创建了某种引用objA的引用对象,但它有一个指向object的类型指针,或者它是一个全新的对象,它恰好指向与objA相同的属性,字段等? 当然,您现在可以访问这两个对象,它们将具有不同的类型,但指向相同的数据。 这是如何运作的?

另一个问题是:GetType()是否保证返回对象的实际类型? 例如,假设有一个带有签名void Method(object sender) ,我们将类型A对象作为参数传递。 sender.GetType()返回类型A还是object ? 为什么?

其他棘手的事情是你可以做(A)obj它会起作用。 CLR现在如何说obj曾经是A型?

如果有人能比“C#通过CLR”更清楚地分解它,那将会很高兴。

更新。 我的不好,应该在发布问题之前运行代码。 因此,如果GetType()确实总是返回真实类型,那么所有其他问题也会变得清晰。

我们知道,C#对象有一个指向其类型的指针,因此当您调用GetType()时,它会检查该指针并返回对象的实际类型。

正确。

如果我这样做:

 class A {} class P { public static void Main() { A objA = new A(); object obj = (object)objA; bool b = obj.GetType() == typeof(object) ; // this is true } } 

不,那是假的。 试试吧!

但是这里发生了什么对象obj =(对象)objA;?

objA中的引用被复制到变量obj。 (除非A是值类型,在这种情况下它被装箱并且对该框的引用被复制到obj。)

它是否创建了某种引用objA的引用对象,但它有一个指向object的类型指针,或者它是一个全新的对象,它恰好指向与objA相同的属性,字段等?

都不是。 它复制参考,期间。 它完全没有变化。

当然,您现在可以访问这两个对象,它们将具有不同的类型,但指向相同的数据。 这是如何运作的?

它没有。 这个问题是基于假设的假设。 他们不会有不同的类型。 它们是相同的参考。 变量有不同的类型,但这是无关紧要的; 你不是要求变量的类型,你要求变量的内容为它的类型。

是GetType()保证返回对象的实际类型?

为了您的目的,是的。 有一些模糊的情况涉及COM互操作,但它没有。

例如,假设有一个带有签名void方法(对象发送者)的方法,我们将类型A的对象作为参数传递。 sender.GetType()会返回类型A还是对象?

A型

为什么?

因为那是对象的类型。

其他棘手的事情是你可以做(​​A)obj它会起作用。 CLR现在如何说obj曾经是A型?

C#编译器生成一个castclass指令。 castclass指令执行运行时检查以validation对象引用是否实现了所需的类型。 如果没有,则CLR抛出exception。