Это происходит потому, что List<int>
не является List<object>
- тип списка не является ковариантным в параметре типа элемента. К сожалению, вам необходимо получить типизированную версию универсального метода и вызвать его с помощью отражения:
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 });
Альтернативой может быть создание версии вашего метода расширения, который принимает IList
вместо IList<T>
. Класс List<T>
реализует этот неуниверсальный интерфейс, а также универсальный интерфейс, поэтому вы сможете вызывать:
public static DataTable WeakToDataTable(this IList list) { ... }
((IList)list).WeakToDataTable();
(В действительности вы, вероятно, использовали бы перегрузку, а не другое имя - просто использовали бы другое имя для вызова различных типов.)
Дополнительная информация: В решении с отражением я пропустил проблему определения типа элемента списка. Это может быть немного сложно в зависимости от того, насколько сложным вы хотите получить. Если вы предполагаете, что объект будет List<T>
(для некоторого T), тогда это просто:
Type listItemType = list.GetType().GetGenericArguments()[0];
Если вы только предполагаете, что IList<T>
, то это немного сложнее, потому что вам нужно найти соответствующий интерфейс и получить общий аргумент из этого. И вы не можете использовать GetInterface (), потому что вы ищете закрытый созданный экземпляр универсального интерфейса. Таким образом, вы должны просматривать все интерфейсы, ища один, который является экземпляром IList<T>
:
foreach (Type itf in list.GetType().GetInterfaces())
{
if (itf.IsGenericType && itf.GetGenericTypeDefinition == typeof(IList<>)) // note generic type definition syntax
{
listItemType = itf.GetGenericArguments()[0];
}
}
Это будет работать для пустых списков, потому что они удаляются из метаданных, а не из содержимого списка.