反射-如何在类型列表之间进行比较

本文关键字:之间 比较 列表 类型 反射 | 更新日期: 2023-09-27 18:27:37

我有一个各种类型的实例列表(所有这些类型都派生自超类型)。我需要得到一个子列表,它只包括某些类型或派生的实例。一个简化的例子可以是:

class Program
{
    private class A { }
    private class B : A { }
    private class C : A { }
    private class D : C { }
    static void Main(string[] args) 
    { 
        B b = new B();
        C c = new C();
        D d = new D();
        var typesToHave = new List<Type>();
        typesToHave.Add(typeof(C));
        var result = new List<A>();
        if (typesToHave.Any(t => b.GetType().IsInstanceOfType(t)))
            result.Add(b);
        if (typesToHave.Any(t => c.GetType().IsInstanceOfType(t)))
            result.Add(c);
        if (typesToHave.Any(t => d.GetType().IsInstanceOfType(t)))
            result.Add(d);
    }
}

我希望这里有一个包含cd的列表,但它什么也不返回。

此外(但这是次要的)我不明白为什么不能在lambda表达式中使用isas运算符,比如:

if (typesToHave.Any(t => d is t))

在上面的例子中,我如何获得一个包含cd的列表?

反射-如何在类型列表之间进行比较

您的参数错误。IsInstanceOfType需要一个实例作为参数,当您传递Type时。

以下内容应该有效。

if (typesToHave.Any(t => t.IsInstanceOfType(d)))

您可以使用IsAssignableFrom

if (typesToHave.Any(t => t.IsAssignableFrom(d.GetType()))

为了使用isas运算符,您需要提供Type名称。不是类型实例,这些操作符就是这样工作的。例如:

var list = new List<int>();
var ie = list as IEnumerable<int>;

这也是一个非常好的替代方案:

if (typesToHave.Any(t => b.GetType().IsSubclassOf(t) || b.GetType() == t))
    result.Add(b);
if (typesToHave.Any(t => c.GetType().IsSubclassOf(t) || c.GetType() == t))
    result.Add(c);
if (typesToHave.Any(t => d.GetType().IsSubclassOf(t) || d.GetType() == t))
    result.Add(d);