为了账号安全,请及时绑定邮箱和手机立即绑定

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

/ 猿问

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

缥缈止盈 2019-08-24 18:04:56

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

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

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

但是,这将失败:

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

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


查看完整描述

3 回答

?
皈依舞

显然,没有。

这是选项:

Type.IsSubclassOf

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

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

输出:

TrueFalse

这表明它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 { }

在这里你得到以下输出:

TrueTrueTrue

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

所以IsAssignableFrom也不完全正确。

is 和 as

“问题”与isas你的问题的背景是,他们会要求你对对象进行操作和写直接在代码中的类型之一,而不是与工作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;}


查看完整回答
反对 回复 2019-08-24
?
慕容3067478

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

错误:'Type'不包含'IsAssignableFrom'的定义,并且没有扩展方法'IsAssignableFrom'可以找到接受类型'Type'的第一个参数(你是否缺少using指令或汇编引用?)

因为IsAssignableFrom请求一个TypeInfo对象。您可以使用以下GetTypeInfo()方法System.Reflection

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


查看完整回答
反对 回复 2019-08-24
?
慕姐4208626

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

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


查看完整回答
反对 回复 2019-08-24

添加回答

回复

举报

0/150
提交
取消
意见反馈 邀请有奖 帮助中心 APP下载
官方微信