您如何确定给定的类型(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
如果给定的类型是
指定类型或派生自指定类型。
因此,如果您使用这些来比较 BaseClass
和 DerivedClass
(继承自 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))
进行比较,以确定它是否正是我们正在寻找的类型。(如您所知,与 is
或 as
运算符的工作方式不同)。当我们只有精确比较的类型时,我们就没有机会了。以上是关于您如何确定给定的类型(System.Type)是不是继承自特定的基类(在 .Net 中)?的主要内容,如果未能解决你的问题,请参考以下文章
如何确定给定时区中的给定时间是不是在postgresql中是DST?