您如何确定给定的类型(System.Type)是不是继承自特定的基类(在 .Net 中)?

Posted

技术标签:

【中文标题】您如何确定给定的类型(System.Type)是不是继承自特定的基类(在 .Net 中)?【英文标题】:How do you determine whether or not a given Type (System.Type) inherits from a specific base class (in .Net)?您如何确定给定的类型(System.Type)是否继承自特定的基类(在 .Net 中)? 【发布时间】:2010-09-12 20:35:21 【问题描述】:

这很可能是一个简单的答案,我只是遗漏了一些东西,但是这里......如果我有一个类型,(即,一个实际的 System.Type......不是一个实例)怎么办我告诉它是否继承自另一个特定的基类型?

【问题讨论】:

请注意Type.IsSubclassOf 方法不适用于泛型类型! Take a look at this article 用于实现也适用于泛型的 IsSubclassOf 方法。 【参考方案1】:

编辑:请注意,如果您要查找的基本类型是接口,则上述解决方案将失败。以下解决方案适用于任何类型的继承,无论是类还是接口。

// Returns true if "type" inherits from "baseType"
public static bool Inherits(Type type, Type baseType) 
    return baseType.IsAssignableFrom(type)

(Semi)MSDN 文章的有用摘录:

如果 [参数] 和当前 Type 表示相同的类型,或者当前 Type 在 [参数] 的继承层次结构中,或者当前 Type 是 [参数] 实现的接口,则为 true,或者如果 [参数] 是泛型类型参数并且当前类型表示 [参数] 的约束之一。如果这些条件都不为真,或者 [参数] 为空引用(在 Visual Basic 中为 Nothing),则为 false。

【讨论】:

是的,与 Type.IsSubclassOf 不同,这也适用于接口。【参考方案2】:

使用System.Type 类的IsSubclassOf 方法。

【讨论】:

对于接口,有GetInterface方法 所以...这并不能完全回答问题。如果类型 a 实现接口 b,它将不起作用 为了包含接口,最好使用 IsAssignableFrom() 作者要求“从特定基类继承”,不是吗? 我更喜欢 IsInstanceOfType 而不是 IsAssignableFrom。但请注意 STW 的回答,这些在比较相同类型(非派生)的实例时返回 true,其中 IsSubClassOf 将返回 false【参考方案3】:

Type.IsSubTypeOf()Type.IsAssignableFrom() 之间需要澄清一点:

IsSubType() 将返回 true 仅当给定类型派生自 指定的类型。如果给定类型 IS,它将返回 false 指定的类型。

IsAssignableFrom() 将返回 true 如果给定的类型是 指定类型或派生自指定类型。

因此,如果您使用这些来比较 BaseClassDerivedClass(继承自 BaseClass),那么:

BaseClassInstance.GetType.IsSubTypeOf(GetType(BaseClass)) = FALSE
BaseClassInstance.GetType.IsAssignableFrom(GetType(BaseClass)) = TRUE

DerivedClassInstance.GetType.IsSubTypeOf(GetType(BaseClass)) = TRUE
DerivedClassInstance.GetType.IsAssignableFrom(GetType(BaseClass)) = TRUE

【讨论】:

实际上,DerivedClassInstance.GetType.IsAssignableFrom(GetType(BaseClass)) 将返回 FALSE。您需要以相反的方式应用它:typeof(BaseClass).IsAssignableFrom(typeof(DerivedClass))。换句话说,您不能执行以下操作: DerivedClass c = new BaseClass(); IsAssignableFrom 正在测试什么 如果你手里只有这个类型。比如propertyInfo.PropertyType如何判断一个接口是否是从这个类型实现的? IsAssignableFrom 只是提供了它们之间的兼容性。举一个更清楚的例子;我无法找到一个类型是否真的完全是 IList,而不是类型 List。这可能是 IList 驱动的另一件事。这应该是多态问题。 @DavutGürbüz 接口与类是不同的问题,但您的方案听起来像是代码异味。接口实现在哪里声明无关紧要——如果你的类直接或间接实现了一个接口,那么它应该可以与所有其他实现互换。否则你就违反了 Liskov 的替换原则。 是的,这就是我的意思。是的,我们可能会认为这是代码气味,我想说的接口或子类无关紧要,这取决于 Liskov 的规则,您无法从 IsAssignableFrom 方法中得到太多。但是,如果您有一个实例,您可以通过 (instance.GetType() == typeOf(IList)) 进行比较,以确定它是否正是我们正在寻找的类型。(如您所知,与 isas 运算符的工作方式不同)。当我们只有精确比较的类型时,我们就没有机会了。

以上是关于您如何确定给定的类型(System.Type)是不是继承自特定的基类(在 .Net 中)?的主要内容,如果未能解决你的问题,请参考以下文章

无论数据类型如何,检查给定数据是不是为非空?

如何识别文件是不是是java中的命名管道

如何:给定 HWND,发现窗口是不是是模态的

如何确定给定时区中的给定时间是不是在postgresql中是DST?

如何确定给定日期是不是在 .NET 2.0 中给定时区的夏令时?

如何确定删除给定循环是不是会断开图表