开发者

GetGenericTypeDefinition returning false when looking for IEnumerable<T> in List<T>

Following this question, why does enumerable in this:

Type type = typeof(List<string>);
bool enumerable = (type.IsGenericType && type.GetGenericTyp开发者_StackOverflow社区eDefinition() == typeof(IEnumerable<>));

return false?


Edit 1

As the above doesn't work, what would be the best way to determine if a class implements IEnumerable?


Here, I might use GetListType(type) and check for null:

static Type GetListType(Type type) {
    foreach (Type intType in type.GetInterfaces()) {
        if (intType.IsGenericType
            && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
            return intType.GetGenericArguments()[0];
        }
    }
    return null;
}


Because

(typeof(List<String>)).GetGenericTypeDefinition()

is returning

typeof(List<>)

GetGenericTypeDefinition can only return one type, not all the unbound types implemented by the target instance of Type.

To determine if X<T> implements IY<T> either

  • Reify T (i.e. make it a real type), and check with concrete types. I.e. does X<string> implement IY<string>. This can be done via reflection or with the as operator.

  • Type.GetInterafces() (or Type.GetInterface(t)).

The second is going to be easier. Especially as this also gives false:

Type t = typeof(List<string>).GetGenericTypeDefinition();
bool isAssign = typeof(IEnumerable<>).IsAssignableFrom(t);


If you want a quick test for specific closed generic types - for example, to check if List<string> implements IEnumerable<string> - then you can do something like this:

Type test = typeof(List<string>);
bool isEnumerable = typeof(IEnumerable<string>).IsAssignableFrom(test);

If you want a more general-purpose solution that works for any IEnumerable<T> then you'll need to use something like this instead:

Type test = typeof(List<string>);
bool isEnumerable = test.GetInterfaces().Any(i =>
    i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(IEnumerable<>)));


The following returns true and is kind of to the point, checking the interfaces:

 enumerable = typeof(List<string>).GetInterfaces()
               .Contains(typeof(IEnumerable<string>));
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜