Beakie
Beakie

Reputation: 1999

How to find out if a type implements generics base class

Using the example below... how can I find out whether a property is of a type implementing generics class Foo?

public class Foo<TBaz>
{

}

public class Bar
{
    public Foo<int> FooInt { get; set; }
    public Foo<string> FooString { get; set; }
    public double SomeOther { get; set; }

    public int GetFooCount()
    {
        return typeof(Bar).GetProperties().Where(p => p.GetType().IsGenericType).Count();
    }
}

If I wanted to find Foo<int>, it would be easy, but how can I find out if it contains Foo<int>, Foo<double> etc...?

I have written the bit of GetFooCount() I have so far...

Thanks

Upvotes: 1

Views: 55

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1062502

return typeof(Bar).GetProperties().Where(p => p.PropertyType.IsGenericType
    && p.PropertyType.GetGenericTypeDefinition() == typeof(Foo<>)).Count();

Note: this won't automatically work for class NonGenericSubtype : Foo<Blah> {...}, nor will it work for class GenericSubtype<T> : Foo<T> {...} - if you need to handle those, it gets more fun.

For the more general case, you would need something that uses recursion on the type:

public static int GetFooCount()
{
    return typeof(Bar).GetProperties()
        .Count(p => GetFooType(p.PropertyType) != null);
}

private static Type GetFooType(Type type)
{
    while(type != null)
    {
        if (type.IsGenericType &&
            type.GetGenericTypeDefinition() == typeof(Foo<>))
                return type.GetGenericArguments()[0];
        type = type.BaseType;
    }
    return null;
}

Note this also answers "now how do I find T?"

Upvotes: 2

Related Questions