要检查一个类型是否是C#中另一个类型的子类,很简单:

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


但是,这将失败: br />
是否可以使用OR运算符或扩展方法来检查类型是否是基类本身的子类或基类?

#1 楼

显然,没有。

以下是这些选项:


使用Type.IsSubclassOf

使用Type.IsAssignableFrom

/>
isas


Type.IsSubclassOf

您已经发现,如果这两种类型是同样,这是一个示例LINQPad程序,它演示了:

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

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


输出:是Derived的子类,但Base(显然)不是其自身的子类。

Type.IsAssignableFrom

现在,这将回答您的特定问题,但它将也给您带来误报。正如埃里克·利珀特(Eric Lippert)在评论中指出的那样,尽管该方法确实会为上述两个问题返回Base,但对于以下两个问题,它也将返回True: />
在这里您得到以下输出: True或它们是同一类型,显然不是这种情况。

所以True也不完全正确。


uint[]int[] IsAssignableFrom和is的“问题”是它们将要求您对对象进行操作并直接在代码中编写一种类型,而不能与as一起使用对象。

换句话说,它将不会编译:

True
False


也不会这样:

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 { }


也不会:

q4312 078q

结论

虽然上述方法可能满足您的需求,但对您问题的唯一正确答案(如我所见)是您将需要进行额外检查: br />
True
True
True


当然,在方法上更有意义:

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


评论


谢谢!我将其标记为正确答案(必须再等待8分钟),因为您提到必须取消检查并提供了指向MSDN文档的链接。

–丹尼尔·T。
2010-4-30在4:30

请注意,这实际上并没有执行问题所要求的;这并不能确定一种类型是否是另一种类型的子类,而是一种类型是否与另一种类型兼容。 uint数组不是int数组的子类,但是它们是赋值兼容的。 IEnumerable 不是IEnumerable 的子类,但它们在v4中是兼容的。

–埃里克·利珀特
2010-4-30的6:07

IsInstanceOfType如何适合这个?

–Lennart
16年7月18日在7:40

为什么typeof(List )。IsSubclassOf(typeof(IList ))返回false?

– Nilesh Barai
19-10-25在8:25

@NileshBarai因为一个类不是它实现的接口的子类。使用typeof(Test).GetInterfaces()。Contains(typeof(ITest))来测试一个类是否实现了接口,或者使用typeof(ITest).IsAssignableFrom(typeof(Test))

–拉瑟·V·卡尔森(Lasse V. Karlsen)
19-10-25在11:12



#2 楼

typeof(BaseClass).IsAssignableFrom(unknownType);


#3 楼

您应该尝试使用Type.IsAssignableFrom。

#4 楼

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


错误:“类型”不包含“ IsAssignableFrom”的定义并且
找不到扩展方法'IsAssignableFrom'接受
类型'Type'的第一个参数(是否缺少using指令或
程序集引用?) />
因为IsAssignableFrom要求一个TypeInfo对象。
您可以使用GetTypeInfo()中的System.Reflection方法:

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

#5 楼

我正在发布此答案,希望有人与我分享是否以及为什么这不是一个好主意。在我的应用程序中,我具有要检查的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;
        }
    }
}


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

评论


这个想法有两个问题:1)类型需要一个无参数的构造函数,否则CreateInstance将失败; 2)如果无法进行强制转换,则抛出对(A)的强制转换不会返回null; 3)您实际上不需要新实例,因此您有无用的分配。可接受的答案更好(尽管不完美)。

–马塞尔·波佩斯库(Marcel Popescu)
17年12月7日在19:37

感谢您的反馈。很有帮助。

–baskren
17年12月8日在20:35

最近发表