当从基类调用GetType()时,它是否会返回最派生的类型?

137

当从基类调用GetType()方法时,它会返回最派生的类型吗?

例如:

public abstract class A
{
    private Type GetInfo()
    {
         return System.Attribute.GetCustomAttributes(this.GetType());
    }
}

public class B : A
{
   //Fields here have some custom attributes added to them
}

还是我应该创建一个抽象方法,由派生类实现,像以下这样?

public abstract class A
{
    protected abstract Type GetSubType();

    private Type GetInfo()
    {
         return System.Attribute.GetCustomAttributes(GetSubType());
    }
}

public class B : A
{
   //Fields here have some custom attributes added to them

   protected Type GetSubType()
   {
       return GetType();
   }
}

13
好的,你试过了吗? - BrokenGlass
3
通常我会这样做,但我现在没有电脑……只是用手机发帖,因为一个问题的解决方案开始形成了,我很好奇现在就知道它!=PTranslated: 通常情况下我会这样做,但我现在没有电脑……只是用手机发布了这篇文章,因为一个问题的解决方案开始浮现,我好奇想现在就知道!=P - Matthew Cox
4个回答

157

GetType()会返回实际的、实例化的类型。在你的情况下,如果你调用B实例上的GetType(),它将返回typeof(B),即使变量被声明为对A的引用。

你的GetSubType()方法没有必要。


它真的这样吗?我正在从其(抽象)超类传递对象实例,接收器只看到超类。它不是总会返回句柄定义的内容而不是实例吗?-或者我漏掉了什么? - user359135
1
啊哈..区别在于使用TypeOf(X)和x.GetType(),我想。 - user359135

25

GetType 方法始终返回实际实例化的类型,即最派生的类型。这意味着你的 GetSubType 行为就像 GetType 本身一样,因此是不必要的。

要静态地获取某个类型的类型信息,可以使用 typeof(MyClass)

然而,你的代码有一个错误: System.Attribute.GetCustomAttributes 返回 Attribute[] 而不是 Type


12

GetType 总是返回实际类型。

其原因深藏在.NET框架和CLR中,因为JIT和CLR使用 .GetType方法在内存中创建一个 Type 对象,该对象保存有关对象的信息,并且所有访问和编译都通过此 Type 实例进行。

如需了解更多信息,请参阅微软出版的《CLR via C#》一书。


1

输出:

GetType:
        Parent: 'Playground.ParentClass'
        Child: 'Playground.ChildClass'
        Child as Parent: 'Playground.ChildClass'

GetParentType:
        Parent: 'Playground.ParentClass'
        Child: 'Playground.ParentClass'
        Child as Parent: 'Playground.ParentClass'

Program.cs:

using Playground;

var parent = new ParentClass();
var child = new ChildClass();
var childAsParent = child as ParentClass;

Console.WriteLine("GetType:\n" +
                  $"\tParent: '{parent.GetType()}'\n" +
                  $"\tChild: '{child.GetType()}'\n" +
                  $"\tChild as Parent: '{childAsParent.GetType()}'\n");

Console.WriteLine("GetParentType:\n" +
                  $"\tParent: '{parent.GetParentType()}'\n" +
                  $"\tChild: '{child.GetParentType()}'\n" +
                  $"\tChild as Parent: '{childAsParent.GetParentType()}'\n");

ChildClass.cs

namespace Playground
{
    public class ChildClass : ParentClass
    {
    }
}

ParentClass.cs

namespace Playground
{
    public class ParentClass
    {
        public Type GetParentType()
        {
            return typeof(ParentClass);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接