Ciò si verifica perché un List<int>
non è un List<object>
- il tipo di elenco non è covariante nel suo parametro tipo di elemento. Purtroppo si avrebbe bisogno di ottenere una versione digitato del metodo generico e chiamare utilizzando la riflessione:
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 });
Un'alternativa potrebbe essere quella di creare una versione del metodo di estensione che accetta IList
piuttosto che IList<T>
. La classe List<T>
implementa questa interfaccia non generica, così come l'interfaccia generica, in modo da essere in grado di chiamare:
public static DataTable WeakToDataTable(this IList list) { ... }
((IList)list).WeakToDataTable();
(In realtà si sarebbe probabilmente utilizzare un sovraccarico piuttosto che un altro nome - usando solo un nome diverso per richiamare i diversi tipi)
Maggiori informazioni:. Nella soluzione riflessione, ho saltato il problema di come determinare il tipo di lista degli elementi. Questo può essere un po 'complicato a seconda di quanto sofisticato vuoi ottenere. Se stai assumendo che l'oggetto sarà un List<T>
(per qualche T) allora è facile:
Type listItemType = list.GetType().GetGenericArguments()[0];
Se siete solo disposto ad assumere IList<T>
allora è un po 'più difficile, perché è necessario individuare l'appropriata interfaccia e ottieni l'argomento generico da quello. E non puoi utilizzare GetInterface() perché stai cercando un'istanza di un'interfaccia generica costruita in modo chiuso. In modo da avere a strisciare attraverso tutte le interfacce alla ricerca di uno che è un'istanza di 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];
}
}
Questo funziona per gli elenchi vuoti perché va fuori i metadati, non il contenuto dell'elenco.
Perché ti rattristi a '' lista
Perché non sa al momento della compilazione quale tipo di lista ha: non sa che è "Lista". Sta cercando di aggirare il problema passando a una classe base (che, come si nota correttamente, non funzionerà perché 'Lista ' non è compatibile con 'Elenco