web-dev-qa-db-fra.com

Initialisation d'un Generic.List en C #

En C #, je peux initialiser une liste en utilisant la syntaxe suivante.

List<int> intList= new List<int>() { 1, 2, 3 };

Je voudrais savoir comment cela {} la syntaxe fonctionne, et si elle a un nom. Il existe un constructeur qui prend un IEnumerable, vous pourriez l'appeler.

List<int> intList= new List<int>(new int[]{ 1, 2, 3 });

Cela semble plus "standard". Lorsque je déconstruit le constructeur par défaut de la liste, je ne vois que

this._items = Array.Empty;

J'aimerais pouvoir le faire.

CustomClass abc = new CustomClass() {1, 2, 3};

Et pouvoir utiliser le 1, 2, 3 liste. Comment cela marche-t-il?

Mise à jour

Jon Skeet a répondu

Il appelle le constructeur sans paramètre, puis appelle Add:

> List<int> tmp = new List<int>();
> tmp.Add(1); tmp.Add(2); tmp.Add(3);
> List<int> intList = tmp;

Je comprends ce que ça fait. Je veux savoir comment. Comment cette syntaxe sait-elle appeler la méthode Add?

Mise à jour

Je sais, comment cliché d'accepter une réponse de Jon Skeet. Mais, l'exemple avec les cordes et les pouces est génial. Une page MSDN très utile est également:

46
Anthony D

Cela s'appelle un initialiseur de collection. Il appelle le constructeur sans paramètre, puis appelle Add:

List<int> tmp = new List<int>();
tmp.Add(1);
tmp.Add(2);
tmp.Add(3);
List<int> intList = tmp;

Les exigences pour le type sont:

  • Il implémente IEnumerable
  • Il a des surcharges de Add qui conviennent aux types d'arguments que vous fournissez. Vous pouvez fournir plusieurs arguments entre accolades, auquel cas le compilateur recherche une méthode Add avec plusieurs paramètres.

Par exemple:

public class DummyCollection : IEnumerable
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new InvalidOperationException("Not a real collection!");
    }

    public void Add(string x)
    {
        Console.WriteLine("Called Add(string)");
    }

    public void Add(int x, int y)
    {
        Console.WriteLine("Called Add(int, int)");
    }
}

Vous pouvez ensuite utiliser:

DummyCollection foo = new DummyCollection
{
    "Hi",
    "There",
    { 1, 2 }
};

(Bien sûr, vous voudriez normalement que votre collection implémente IEnumerable correctement ...)

65
Jon Skeet

Lire Initialiseurs d'objets et de collections (Guide de programmation C #). Fondamentalement, vous pouvez le faire avec chaque type personnalisé qui est une liste (implémente IEnumerable).

7
Cornel

Ils sont appelés initialiseurs de collection (voir aussi ici ), et leur fonctionnement est en recherchant une méthode Add() qui peut faire leur offre. Il appelle Add() pour chacun des entiers que vous avez entre vos accolades.

La recherche de la méthode Add() est une pure magie de compilation. Il est codé en dur pour trouver une méthode de ce nom.

4
mqp

Le nom que vous recherchez est "Collection Initializer". Il fonctionne sous le capot en recherchant une méthode nommée Ajouter sur le type de collection et en l'appelant pour chaque valeur que vous spécifiez.

Plus de détails: initialiseurs d'objets et de collections (Guide de programmation C #)

2
JaredPar

Je pense que c'est un raccourci vers la méthode .Add. Je n'ai jamais essayé de le contourner, donc je ne sais pas si c'est possible.

1
Matt Grande

En ce qui me concerne, l'ajout d'éléments via l'initialisation d'objet recherche une méthode Add. Donc, comme List <int> aura void Add (int), cela fonctionnera.

Pour l'utiliser dans votre classe, ajoutez simplement

class CustomClass { 
   public void Add(int num) {
      // Your code here
   }
}

Votre classe devrait implémenter IEnumerable, comme l'a souligné Hallgrim.

Il utilise en fait le .Add méthode. Ce qui signifie qu'il appelle .Add pour chaque élément entre crochets à l'intérieur du constructeur.

0
Alexander Kahoun