正如我们所知,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()
确实总是返回真实类型,那么所有其他问题也会变得清晰。
答案 0 :(得分:23)
我们知道,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指令执行运行时检查以验证对象引用是否实现了所需的类型。如果没有,则CLR抛出异常。