Convert / Cast IEnumerable to IEnumerable <T>

I have a class (web control) that has a property of type IEnumerable and would like to work with a parameter using LINQ.

Is there a way to cast / convert / call through reflection in IEnumerable <T> without knowing the type at compile time?

Method void (IEnumerable source) { var enumerator = source.GetEnumerator(); if (enumerator.MoveNext()) { var type = enumerator.Current.GetType(); Method2<type>(source); // this doesn't work! I know! } } void Method2<T>(IEnumerable<T> source) {} 
+43
c # linq
May 01 '09 at 18:44
source share
4 answers

Is your Method2 what type it gets? If not, you can simply call Cast<object>() :

 void Method (IEnumerable source) { Method2(source.Cast<object>()); } 

If you definitely need to get the correct type, you will need to use reflection.

Something like:

 MethodInfo method = typeof(MyType).GetMethod("Method2"); MethodInfo generic = method.MakeGenericMethod(type); generic.Invoke(this, new object[] {source}); 

This is not ideal though ... in particular, if the source is not exactly IEnumerable<type> , then the call will fail. For example, if the first element is a string, but the source is a List<object> , you will have problems.

+55
May 01 '09 at 18:48
source share

You probably want to reorganize your code to use IEnumerable.Cast<T>

Use it as follows:

 IEnumerable mySet = GetData(); var query = from x in mySet.Cast<int>() where x > 2 select x; 
+8
May 01 '09 at 18:47
source share

With .NET 4, you can simply pass source to dynamic before passing it to a method. This will resolve the correct general overload at runtime without any ugly reflection code:

 void Method(IEnumerable source) { var enumerator = source.GetEnumerator(); if (enumerator.MoveNext()) { Method2((dynamic)source); } } 

As in Jon's second solution, this will only work if your source is IEnumerable<T> . If this is a simple IEnumerable , you need to create another method that converts it to the correct IEnumerable<T> , as in the following solution:

 IEnumerable<T> Convert<T>(IEnumerable source, T firstItem) { // Note: firstItem parameter is unused and is just for resolving type of T foreach(var item in source) { yield return (T)item; } } void Method(IEnumerable source) { var enumerator = source.GetEnumerator(); if (enumerator.MoveNext()) { dynamic firstItem = enumerator.Current; dynamic typedEnumerable = Convert(source, firstItem); Method2(typedEnumerable); } } 
+3
Sep 25 '13 at 16:05
source share

This is a few years later, but I solved the List<Object> problem.

 void Method(IEnumerable source) { var enumerator = source.GetEnumerator(); if (enumerator.MoveNext()) { MethodInfo method = typeof(MyClass).GetMethod("Method2"); MethodInfo generic; Type type = enumerator.Current.GetType(); bool sameType = true; while (enumerator.MoveNext()) { if (enumerator.Current.GetType() != type) { sameType = false; break; } } if (sameType) generic = method.MakeGenericMethod(type); else generic = method.MakeGenericMethod(typeof(object)); generic.Invoke(this, new object[] { source }); } } 
+2
Aug 14 '13 at 14:42
source share



All Articles