Le type est en fait défini par l'appelant, donc c'est dans le cadre de la fonction d'appel - en évitant soigneusement le problème de "renvoyer" un type anonyme.
Ceci est accompli par l'inférence de type générique. La signature pour Select est Select<Tsource, TResult>(IEnumerable<TSource>, Func<TSource, TResult>
. Le IEnumerable<TSource>
est, évidemment, la collection source. La fonction de transformation Func<Tsource, TResult>
est l'endroit où le compilateur peut utiliser l'inférence de type pour déclarer un type anonyme. En d'autres termes, pour passer un Func<Tsource, TResult>
à Select
, vous devez définir l'appelant TResult
.Ce qui signifie Select
ne renvoie pas un type anonyme défini par lui - mais par vous.
Pour imiter cela, il vous suffit d'obtenir l'appelant pour définir le type:
TResult ReturnAnonymousType<TResult>(Func<TResult> f) {
return f();
}
Console.WriteLine(ReturnAnonymousType(
() => return new { Text = "Hello World!" } // type defined here, before calling
);
En fait, vous pouvez même avoir une liste des types anonymes? Je pense qu'il parlait de quand, au lieu de int, vous avez un type anonyme dans votre exemple. – Guvante
Oui, vous pouvez facilement avoir une liste avec un élément de type anonyme: new [] {new {Name = "Jon"}} .ToList(); –
Il existe également d'autres moyens d'obtenir des listes - par exemple, en écrivant une méthode d'extension et en utilisant une seule instance anon (ou un lambda à un) pour transformer un T en Liste –