È possibile usufruire di farmaci generici e inferenza di tipo per creare l'elenco per voi:
public static List<T> CreateAnonymousList<T>(params T[] entries)
{
return new List<T>(entries);
}
Uso come:
var someList = CreateAnonymousList(new { foo = 1 }, new { foo = 2 }, new { foo = 1 });
someList.Where(x => x.foo == 1);
Naturalmente non sarà in grado di fare molto di con esso. Non sarai mai in grado di scriverlo con forza nel tuo codice a un valore diverso da var
o restituirlo dal tuo metodo o qualsiasi cosa che normalmente non potresti fare con i tipi anonimi. Se vuoi fare di più, devi solo mordere il (piccolo) proiettile e definire una classe per il tuo tipo anonimo.
Rileggendo la tua domanda, è ancora possibile eseguire query LINQ su un array:
var someArray = new[]{new { foo = 1 }, new { foo = 2 }, new { foo = 1 }};
someArray.Where(x => x.foo == 1)
Quindi, a meno che non si sta modificando esso (dite tramite standard di List<T>
operazioni come Add
o Remove
) allora non c'è motivo di devi convertirlo in un List<T>
.
Mi rendo conto che forse si desidera essere ancora in grado di restituirlo (per qualche motivo) e continuare a fare operazioni su di esso senza conoscerne il tipo anonimo. In questo caso si potrebbe trattarlo come dynamic
ed eseguire le operazioni in fase di esecuzione, ma si perde qualsiasi intellisense/strong digitazione che normalmente si ha con il tipo anonimo:
List<dynamic> someDynamicList = new List<dynamic>() {new { foo = 1 }, new { foo = 2 }, new { foo = 1 }};
someDynamicList.Where(x => x.foo == 1)
Un ultimo metodo come sottolineato da Tim Schmelter sfruttando CastByExample di Jon Skeet, ma esteso a convertire la vostra collezione con un metodo di estensione:
public static IEnumerable<T> CastByExample<T>(this IEnumerable source, T example)
{
foreach(object entry in source)
yield return (T)entry;
}
public static IEnumerable CreateAnonymousData()
{
return new[]{new { foo = 1 }, new { foo = 2 }, new { foo = 1 }};
}
con l'utilizzo come:
var anonymousData = CreateAnonymousData();
var typedAnonymousData = anonymousData.CastByExample(new { foo = 1 });
typedAnonymousData.Where(x => x.foo == 1);
Questa sfrutta il fatto che all'interno della stessa assemblea , tipi anonimi dichiarate con gli stessi nomi dei parametri, i tipi, e fine compilare allo stesso tipo.Questo non funzionerà se devi chiamare il tuo CreateAnonymousData
dall'assemblaggio corrente e devi mantenere la firma del tuo tipo anonimo foo
ovunque lo usi (aggiungi/modifica la sua firma, tu devi aggiornalo ovunque tu usalo o avrai un brutto momento).
Ma penso che stia diventando più chiaro ora che la soluzione migliore è semplicemente definire una rappresentazione di classe del tipo anonimo.
perché hai un '' lista
@TimSchmelter Perché 'AnonymousType' è un tipo di' oggetto'. Non esiste un tipo di dati 'anonimo '. Destra? – Johan
I tipi anonimi hanno solo proprietà di sola lettura. – Romoku