Tobia Zambon
Tobia Zambon

Reputation: 7619

Reflection - how to compare between list of types

I've a list of instances of various types (all of this types derive from a supertype). I need to get a sublist that includes only the instances that are of certain types or derived. A simplified example can be:

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

    }
}

What I'm expecting to have here is a list with c and d but it returns nothing.

Also (but it is secondary) I can't figure out why I can't use the is or as operator in the lambda expression, like:

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

How can I have a list with c and d in the example above?

Upvotes: 3

Views: 90

Answers (3)

Faris Zacina
Faris Zacina

Reputation: 14274

This is also an alternative that works pretty good:

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

Upvotes: 1

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73442

You have the parameters wrong. IsInstanceOfType requires an instance as parameter where as you pass Type.

Following should work.

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

Upvotes: 4

Selman Gen&#231;
Selman Gen&#231;

Reputation: 101680

You can use IsAssignableFrom

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

In order to use is or as operator you need to supply a Type name.Not a type instance, that's how those operators work.For example:

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

Upvotes: 3

Related Questions