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

时间:2010-07-21 05:29:18

标签: c#

正如我们所知,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()确实总是返回真实类型,那么所有其他问题也会变得清晰。

1 个答案:

答案 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抛出异常。