Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检查类型是子类型还是对象的类型?_C#_Reflection_Types_Subclass - Fatal编程技术网

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

C# 如何检查类型是子类型还是对象的类型?,c#,reflection,types,subclass,C#,Reflection,Types,Subclass,要检查一个类型是否是C#中另一个类型的子类,很容易: typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true 但是,这将失败: typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false 有没有办法检查一个类型是子类还是基类本身,而不使用或运算符或扩展方法?您应该尝试使用它。显然,没有 typeof(BaseClass).IsAssi

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

typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns true
但是,这将失败:

typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns false
有没有办法检查一个类型是子类还是基类本身,而不使用
运算符或扩展方法?

您应该尝试使用它。

显然,没有

typeof(BaseClass).IsAssignableFrom(unknownType);
以下是选项:

  • 使用
  • 使用
类型.IsSubclassOf 正如您已经发现的,如果这两种类型相同,这将不起作用,下面是一个示例程序,演示:

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

public class Base { }
public class Derived : Base { }
输出:

True
False
这表明
Derived
Base
的一个子类,但
Base
显然不是它自己的一个子类

类型。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[]
,或者它们是相同的类型,这显然不是事实

因此,
IsAssignableFrom
也不完全正确

在您的问题上下文中,
的“问题”是
as
,它们将要求您操作对象并直接在代码中写入其中一种类型,而不是使用
类型
对象

换句话说,这不会编译:

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(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(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;
        }
    }
}

我觉得我在这里可能有点幼稚,所以欢迎任何反馈。

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

错误:“类型”不包含“IsAssignableFrom”的定义,并且 没有扩展方法“IsAssignableFrom”接受的第一个参数为 找不到类型“type”(是否缺少using指令或 装配参考?)

因为
IsAssignableFrom
请求
TypeInfo
对象。 您可以使用
System.Reflection
中的
GetTypeInfo()
方法:


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

谢谢!我将此标记为正确答案(必须再等8分钟),因为您提到必须取消检查并提供指向MSDN文档的链接;这并不确定一个类型是否是另一个类型的子类,而是确定一个类型是否与另一个类型的赋值兼容。uint数组不是int数组的子类,但它们是赋值兼容的。IEnumerable不是IEnumerable的子类,但它们在v4中与赋值兼容。
IsInstanceOfType
如何适应这种情况?为什么
typeof(List)。IsubClassOf(typeof(IList))
返回false?@NileshBarai,因为类不是它实现的接口的子类。使用
typeof(Test).GetInterfaces().Contains(typeof(ITest))
来测试类是否实现了接口,或者
typeof(ITest).IsAssignableFrom(typeof(Test))
这种想法有几个问题:1)类型需要无参数构造函数,否则CreateInstance将失败;2) 对(A)的强制转换不会返回null,如果无法进行强制转换,则会抛出;3) 您实际上不需要新实例,因此您有一个无用的分配。被接受的答案更好(虽然不是完美的)。感谢您的反馈。非常有用。