I wrote this extension method:
public static DataTable ToDataTable<T>(this IList<T> list)
{...}
It works well if called with a type known at compile time:
DataTable tbl = new List<int>().ToDataTable();
But how to call it if the generic type isn’t known?
object list = new List<int>();
...
tbl = Extension.ToDataTable((List<object>)list); // won't work
This occurs because a
List<int>is not aList<object>— the List type is not covariant in its element type parameter. Unfortunately you would need to get a typed version of the generic method and call it using reflection:An alternative may be to create a version of your extension method that accepts
IListrather thanIList<T>. TheList<T>class implements this non-generic interface as well as the generic interface, so you will be able to call:(In reality you’d probably use an overload rather than a different name — just using a different name to call out the different types.)
More info: In the reflection solution, I skipped over the problem of how to determine the list element type. This can be a bit tricky depending on how sophisticated you want to get. If you’re assuming that the object will be a
List<T>(for some T) then it’s easy:If you’re only willing to assume
IList<T>then it’s a bit harder, because you need to locate the appropriate interface and get the generic argument from that. And you can’t use GetInterface() because you’re looking for a closed constructed instance of a generic interface. So you have to grovel through all the interfaces looking for one which is an instance ofIList<T>:This will work for empty lists because it goes off the metadata, not the list content.