反思 - 如何比较类型列表

时间:2014-10-24 08:34:43

标签: c# .net reflection types comparison

我列出了各种类型的实例(所有这些类型都来自超类型)。我需要获得一个子列表,该子列表仅包含某些类型或派生的实例。一个简化的例子可以是:

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的列表?

3 个答案:

答案 0 :(得分:4)

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

以下应该工作。

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

答案 1 :(得分:3)

您可以使用IsAssignableFrom

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

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

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

答案 2 :(得分:1)

这也是一种非常好的选择:

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);