如何检查一个types是一个子types还是一个对象的types?

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

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

但是,这将失败:

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

有没有什么办法来检查一个types是否是基类自身的子类,不使用OR运算符或使用扩展方法?

显然,不。

这里是选项:

  • 使用Type.IsSubclassOf
  • 使用Type.IsAssignableFrom
  • is

Type.IsSubclassOf

正如你已经发现的,如果这两种types是相同的,这将不起作用,下面是一个示例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[]inheritance,或者它们是相同的types,显然不是这种情况。

所以IsAssignableFrom也不完全正确。

is

与问题相关的“问题”在于,它们将要求您对对象进行操作,并直接在代码中编写其中一种types,而不能使用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; } 
 typeof(BaseClass).IsAssignableFrom(unknownType); 

你应该尝试使用Type.IsAssignableFrom来代替。

我发布这个答案,希望有人与我分享,如果为什么这将是一个坏主意。 在我的应用程序中,我有一个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; } } } 

我觉得我可能会有点天真,所以任何反馈都会受到欢迎。