当你做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。