代码之家  ›  专栏  ›  技术社区  ›  Egor Pavlikhin

当您执行getType()时,实际会发生什么?

c#
  •  6
  • Egor Pavlikhin  · 技术社区  · 14 年前

    如我们所知,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)obj 它会起作用的。clr现在怎么办? obj 曾经是那种 ?

    如果有人能把它分解得比“通过clr的c”更清楚一点,我会很高兴的。

    更新。 我的错,应该在发布问题之前运行代码。所以,如果 获得Type() 真的总是返回真正的类型,比所有其他的问题都清楚。

    1 回复  |  直到 14 年前
        1
  •  23
  •   Eric Lippert    14 年前

    如我们所知,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但有指向对象的类型指针的引用对象,或者它是一个全新的对象,恰好指向与obja相同的属性、字段等?

    两者都不。它复制了参考文献,句号。它是完全不变的。

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

    事实并非如此。这个问题是以一个错误的假设为前提的。它们不会有不同的类型。它们是相同的参考。这个 变量 有不同的类型,但这是不相关的;您不是在询问变量的类型,而是在询问 内容 变量的类型。

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

    为了你的目的,是的。在涉及到COM互操作的情况下,有些情况并不明显。

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

    A型

    为什么?

    因为这就是对象的类型。

    另一个棘手的问题是你可以做obj,它会起作用。clr现在该如何处理obj曾经是A类型?

    C编译器生成一个castclass指令。castclass指令执行运行时检查,以验证对象引用是否实现了所需的类型。如果没有,那么clr将抛出异常。