This is because the List<int> not a List<object> - the List type is not covariant in its element type parameter. Unfortunately, you will need to get a typed version of the general method and call it using reflection:
Type listItemType = typeof(int); // cheating for simplicity - see below for real approach MethodInfo openMethod = typeof(Extension).GetMethod("ToDataTable", ...); MethodInfo typedMethod = openMethod.MakeGenericMethod(typeof(listItemType)); typedMethod.Invoke(null, new object[] { list });
An alternative would be to create a version of your extension method that accepts IList , not IList<T> . The List<T> class implements this non-generic interface, as well as a generic interface, so you can call:
public static DataTable WeakToDataTable(this IList list) { ... } ((IList)list).WeakToDataTable();
(Actually, you would probably use overloading rather than a different name, just using a different name to call different types.)
Additional information: In the reflection solution, I missed the problem of determining the type of the list item. It can be a little trickier depending on how sophisticated you are. If you assume that the object will be List<T> (for some T), then it is easy:
Type listItemType = list.GetType().GetGenericArguments()[0];
If you are only ready to accept IList<T> , then this is a little more complicated, because you need to find the appropriate interface and get a general argument from this. And you cannot use GetInterface () because you are looking for a private, configured instance of a generic interface. Thus, you should be familiar with all the interfaces that are looking for an instance of IList<T> :
foreach (Type itf in list.GetType().GetInterfaces()) { if (itf.IsGenericType && itf.GetGenericTypeDefinition == typeof(IList<>))
This will work for empty lists, since it is disconnected from the metadata, not the contents of the list.
itowlson
source share