web-dev-qa-db-fra.com

Déclaration de types anonymes

Est-il possible de déclarer un objet de liste de type anonyme? je veux dire

List<var> someVariable = new List<var>();
someVariable.Add(
             new{Name="Krishna", 
                 Phones = new[] {"555-555-5555", "666-666-6666"}}
                );

C'est parce que j'ai besoin de créer une collection au moment de l'exécution.

74
Krishna

Cela implique un peu de piratage mais cela peut être fait.

static List<T> CreateListFromSingle<T>(T value) {
  var list = new List<T>();
  list.Add(value);
  return list;
}

var list = CreateListFromSingle(
   new{Name="Krishna", 
                 Phones = new[] {"555-555-5555", "666-666-6666"}}
                );
60
JaredPar

comment sur dynamique?

List<dynamic> dynamicList = new List<dynamic>();


dynamicList.Add(new { Name = "Krishna",  Phones = new[] { "555-555-5555", "666-666-6666" } }); 
78
Jai Kannah

Vous pouvez faire une liste comme celle-ci, mais vous devrez encore une fois utiliser un hackery sérieux, et vous devrez utiliser des situations de type par exemple. Par exemple:

// create the first list by using a specific "template" type.
var list = new [] { new { Name="", Phones=new[] { "" } } }.ToList();

// clear the list.  The first element was just an example.
list.Clear();

// start adding "actual" values.
list.Add(new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } });
53
David Morton

En général, vous pouvez utiliser la formule (sans doute odorante) de l'exemple utilisé par d'autres astuces pour créer des instances de tout type générique paramétrées avec un type anonyme pour l'argument de type. Cependant, pour List<T> il existe une façon un peu moins grossière de le faire:

var array = new[] {
  new {  
    Name="Krishna",  
    Phones = new[] {"555-555-5555", "666-666-6666"}
  }
};
var list = array.ToList();

Votre esquisse d'une syntaxe proposée est similaire à une fonctionnalité que nous n'avons pas implémentée pour C # 3 ou 4, mais que nous avons envisagée. Nous appelons la fonctionnalité "types Mumble", et cela ressemblerait à ceci:

List<?> myList = new List<?>() {
  new {  
    Name="Krishna",  
    Phones = new[] {"555-555-5555", "666-666-6666"}
  }
};

Nous l'appelons "types mumble" parce que bien sûr vous le liriez "maListe est une nouvelle liste de hrmmf". :-)

L'idée est que le compilateur examine les initialiseurs et fasse de son mieux pour déterminer le type possible, de la même manière que "var" signifie "examine l'initialiseur et détermine le type de la variable. ". Que nous utilisions "var" comme "mumble" ou "?" (ce qui est similaire à ce que Java fait dans une fonctionnalité connexe) ou autre chose est une question ouverte.

En tout état de cause, je ne retiendrais pas mon attente en attendant cette fonctionnalité si j'étais toi. Pour l'instant, cela n'a pas encore été envisagé pour plusieurs versions linguistiques, mais je pense que cela restera encore longtemps sur la liste des possibilités. Si, de façon hypothétique, nous devions concevoir les versions futures du langage. Que nous pourrions ou ne pourrions pas être. N'oubliez pas que les réflexions d'Eric sur les futures versions de C # ont uniquement un but de divertissement.

26
Eric Lippert

Vous ne pouvez pas créer une collection de type anonyme comme ceci.

Si vous avez besoin de faire cela, vous devrez soit utiliser List<object>, ou créez une classe ou une structure personnalisée pour votre type.


Modifier:

Je vais reformuler ceci:

Bien que, techniquement, il soit possible de faire une liste de type anonyme, je recommande fortement de ne jamais le faire. Il y a presque toujours une meilleure approche, car cela ne fait que créer un code quasiment impossible à maintenir. Je recommande fortement de créer un type personnalisé pour conserver vos valeurs au lieu d'utiliser des types anonymes.

Un type personnalisé aura toutes les mêmes fonctionnalités (puisque les types anonymes sont définis, par le compilateur, au moment de la compilation), mais sera beaucoup plus compréhensible pour le développeur qui vous suit ...


Et juste pour jouer aussi, voici mon entrée pour "code que je n’aurais jamais vraiment envie d’utiliser dans le monde réel":

var customer = new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } };
var someVariable = new[]{1}.Select(i => customer).ToList();
15
Reed Copsey

Voici une approche qui est un peu plus propre que la plupart des autres suggestions:

var list = Enumerable.Repeat(new { Name = "", Phones = new[] { "" } }, 0)
               .ToList();

// ...
list.Add(new { Name = "Krishna", 
               Phones = new[] { "555-555-5555", "666-666-6666" } });
13
Ian Mercer

J'ai passé beaucoup de temps à essayer de trouver un moyen de gagner du temps en utilisant une liste de types anonymes, puis je me suis rendu compte qu'il était probablement plus rapide d'utiliser simplement une classe privée dans la classe actuelle ...

private class Lookup {
    public int Index;
    public string DocType;
    public string Text;
}
private void MyMethod() {
    List<Lookup> all_lookups = new List<Lookup> {
        new Lookup() {Index=4, DocType="SuperView", Text="SuperView XML File"},
        new Lookup() {Index=2, DocType="Word", Text="Microsoft Word Document"}
    };
    // Use my all_lookups variable here...

}
9
Jonathan

Je ne pense pas que ce soit possible. Peut-être en C # 4 en utilisant le mot-clé dynamic?

2
Robert Massa