如何检查类型是子类型还是对象类型?

时间:2010-04-30 04:23:34

标签: c# reflection types subclass

要检查类型是否是C#中另一种类型的子类,这很容易:

typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true

然而,这将失败:

typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false

有没有办法检查类型是否是基类本身的子类OR,而不使用OR运算符或使用扩展方法?

5 个答案:

答案 0 :(得分:449)

显然,没有。

以下是选项:

Type.IsSubclassOf

正如您已经发现的那样,如果两种类型相同,这将不起作用,这是一个示例LINQPad示例:

void Main()
{
    typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
    typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}

public class Base { }
public class Derived : Base { }

输出:

True
False

这表明DerivedBase的子类,但Base(显然)不是其自身的子类。

Type.IsAssignableFrom

现在,这将回答您的特定问题,但它也会给您误报。正如Eric Lippert在评论中指出的那样,虽然该方法确实会针对上述两个问题返回True,但它也会返回True这些,您可能不想要这些:

void Main()
{
    typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
    typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
    typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}

public class Base { }
public class Derived : Base { }

您可以在此处获得以下输出:

True
True
True

最后True表示,如果方法回答了问题,则uint[]继承自int[]或者他们是相同的类型,显然不是这种情况。

所以IsAssignableFrom也不完全正确。

isas

问题上下文中isas的“问题”是,它们会要求您对对象进行操作并直接在代码中编写其中一种类型,而不是使用Type个对象。

换句话说,这不会编译:

SubClass is BaseClass
^--+---^
   |
   +-- need object reference here

也不会:

typeof(SubClass) is typeof(BaseClass)
                    ^-------+-------^
                            |
                            +-- need type name here, not Type object

也不会:

typeof(SubClass) is BaseClass
^------+-------^
       |
       +-- this returns a Type object, And "System.Type" does not
           inherit from BaseClass

结论

虽然上述方法可能符合您的需求,但您的问题(我认为)的唯一正确答案是您需要额外检查:

typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);

当然在方法中更有意义:

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase)
           || potentialDescendant == potentialBase;
}

答案 1 :(得分:28)

typeof(BaseClass).IsAssignableFrom(unknownType);

答案 2 :(得分:8)

您应该尝试使用Type.IsAssignableFrom

答案 3 :(得分:1)

如果您尝试在Xamarin Forms PCL项目中执行此操作,则使用IsAssignableFrom的上述解决方案会出错:

  

错误:'类型'不包含'IsAssignableFrom'的定义   没有扩展方法'IsAssignableFrom'接受第一个参数   可以找到类型'类型'(您是否缺少使用指令或   装配参考?)

因为IsAssignableFrom要求TypeInfo个对象。 您可以使用GetTypeInfo()中的System.Reflection方法:

typeof(BaseClass).GetTypeInfo().IsAssignableFrom(typeof(unknownType).GetTypeInfo())

答案 4 :(得分:0)

我发布这个答案,希望有人与我分享,如果这是一个坏主意。在我的应用程序中,我有一个Type的属性,我想检查以确保它是typeof(A)或typeof(B),其中B是从A派生的任何类。所以我的代码:

public class A
{
}

public class B : A
{
}

public class MyClass
{
    private Type _helperType;
    public Type HelperType
    {
        get { return _helperType; }
        set 
        {
            var testInstance = (A)Activator.CreateInstance(value);
            if (testInstance==null)
                throw new InvalidCastException("HelperType must be derived from A");
            _helperType = value;
        }
    }
}

我觉得我在这里可能有点天真,所以欢迎任何反馈。

相关问题