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

Dan*_* T. 322 c# reflection types subclass

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

typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true
Run Code Online (Sandbox Code Playgroud)

但是,这将失败:

typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false
Run Code Online (Sandbox Code Playgroud)

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

ang*_*son 476

显然,没有.

这是选项:

Type.IsSubclassOf

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

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

public class Base { }
public class Derived : Base { }
Run Code Online (Sandbox Code Playgroud)

输出:

True
False
Run Code Online (Sandbox Code Playgroud)

这表明它Derived是一个子类Base,但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 { }
Run Code Online (Sandbox Code Playgroud)

在这里你得到以下输出:

True
True
True
Run Code Online (Sandbox Code Playgroud)

最后一个True表明,如果该方法回答了所提出的问题,那么它uint[]继承自int[]或者它们是相同的类型,显然不是这种情况.

所以IsAssignableFrom也不完全正确.

isas

"问题"与isas你的问题的背景是,他们会要求你对对象进行操作和写直接在代码中的类型之一,而不是与工作Type对象.

换句话说,这将无法编译:

SubClass is BaseClass
^--+---^
   |
   +-- need object reference here
Run Code Online (Sandbox Code Playgroud)

这也不会:

typeof(SubClass) is typeof(BaseClass)
                    ^-------+-------^
                            |
                            +-- need type name here, not Type object
Run Code Online (Sandbox Code Playgroud)

这也不会:

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

结论

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

typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);
Run Code Online (Sandbox Code Playgroud)

这当然在一种方法中更有意义:

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase)
           || potentialDescendant == potentialBase;
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这实际上并不是问题所要求的; 这不确定一个类型是否是另一个类型的子类,而是一个类型是否与另一个类型兼容.uint数组不是int数组的子类,但它们是赋值兼容的.IEnumerable <Giraffe>不是IEnumerable <Animal>的子类,但它们在v4中是赋值兼容的. (70认同)
  • 谢谢!我将此标记为正确答案(需要等待8分钟以上),因为您提到必须反转检查并提供MSDN文档的链接. (2认同)
  • `IsInstanceOfType`如何适合这个? (2认同)

Mar*_*ell 34

typeof(BaseClass).IsAssignableFrom(unknownType);
Run Code Online (Sandbox Code Playgroud)


Tho*_*mas 11

您应该尝试使用Type.IsAssignableFrom.