2010-04-01 9 views
2

je compris, normalement génériques est pour le temps sûr et nous compilation permet de garder collection.Then fortement typé comment ne génériques nous permettent de stocker des types anonymes commeGénériques et type anonyme

List<object> TestList = new List<object>(); 
TestList.Add(new { id = 7, Name = "JonSkeet" }); 
TestList.Add(new { id = 11, Name = "Marc Gravell" }); 
TestList.Add(new { id = 31, Name = "Jason" }); 
+0

@nettguy - étrange vous avez utilisé des membres d'ici pour remplir votre liste. – JonH

+1

Même les types anonymes dérivent de 'Object'. –

+1

Clarification: Tout ce qui exclut les types de pointeurs est convertible en objet. Tout ne dérive pas réellement de l'objet. http://blogs.msdn.com/ericlippert/archive/2009/08/06/not-everything-derives-from-object.aspx –

Répondre

9

Cela fonctionne car object est le type racine de toutes les instances dans .Net. Par conséquent, n'importe quelle expression peut être utilisée pour un emplacement qui attend un object parce qu'ils répondent tous au contrat de base de .

Par exemple, ce qui suit est complètement légal.

List<object> TestList = new List<object>(); 
TestList.Add(new { id = 7, Name = "JonSkeet" }); 
TestList.Add("Foo"); 
TestList.Add(42); 
+0

Comment renvoyer le premier élément étant donné que vous n'avez pas de type déclaré que vous pouvez référencer? – jocull

7

Parce que tout est (ou peut être encadré dans) un object, et c'est un List de object s.

+0

Pour être pédant, il faut dire 'ou peut être ** converti ** en' . – SolutionYogi

6

D'autres déjà expliqué pourquoi votre code fonctionne - votre exemple est fortement typé, parce que tout est un objet, mais cela signifie que ce n'est pas très utile. Vous ne pouvez pas prendre des éléments de la liste et accéder par exemple à leur propriété Name, car ils ne sont que des objets, donc cela ne peut pas fonctionner en général.

Cependant, il est possible de créer un fortement typé List des types anonymes - il a juste besoin d'être fait en utilisant une petite méthode utilitaire comme ceci:

static List<T> CreateList<T>(params T[] items) { 
    return items.ToList(); 
} 

Le problème est que vous ne pouvez pas appeler un constructeur sans fournir le nom du type. Lors de l'appel d'une méthode, C# peut déduire le paramètre de type, de sorte que vous pouvez écrire ceci:

var testList = CreateList(
    new { id = 7, Name = "JonSkeet" }, 
    new { id = 11, Name = "Marc Gravell" }); 
testList.Add(new { id = 31, Name = "Jason" }); 

C'est typées parfaitement et vous pouvez par exemple écrire testList[0].Name pour obtenir le nom de la première personne. Si vous essayez d'écrire quelque chose comme testList.Add(42), vous obtiendrez une erreur de compilation, car la liste est fortement typée pour ne contenir que des types anonymes avec les propriétés id et Name.

+0

+1 Fascinant, et a dit avec éloquence. Je me retrouve à me demander dans quel scénario réel voudriez-vous utiliser des listes d '«objets anonymes» autrement que comme une forme de «dissimulation» du code? Un autre "aha" moment qui attend là, je suis sûr :) – BillW

+0

@BillW: C'est une chose de commodité; cela vous évite d'avoir à définir votre propre petit type d'aide. Maintenant qu'il y a un type de Tuple standard dans le framework, le cas d'utilisation pour sauter des arceaux pour faire des listes de type anonyme est beaucoup plus faible. –

+0

Incidemment, cette technique est souvent appelée "cast by example". Si vous recherchez cette phrase sur SO, vous trouverez un certain nombre de questions où les gens tentent de construire des listes, des dictionnaires, etc. –

Questions connexes