MSDN déclare que :
En utilisant un initialisateur de collection, vous ne devez pas spécifier plusieurs appels à la méthode Add de la classe dans votre code source ; le compilateur ajoute les appels.
Ils donnent également cet exemple, qui utilise la nouvelle syntaxe d'initialisation des collections avec des parenthèses :
var numbers = new Dictionary<int, string> {
[7] = "seven",
[9] = "nine",
[13] = "thirteen"
};
Cependant, en vérifiant le code IL généré, il semble que ce code ne donne lieu à aucun appel à la fonction Add
mais plutôt à une set_item
comme ça :
IL_0007: ldstr "seven"
IL_000c: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::set_Item(!0/*int32*/, !1/*string*/)
L'"ancienne" syntaxe avec des crochets en revanche donne ce qui suit :
// C# code:
var numbers2 = new Dictionary<Int32, String>
{
{7, "seven"},
{9, "nine"},
{13, "thirteen"}
};
// IL code snippet:
// ----------
// IL_0033: ldstr "seven"
// IL_0038: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0/*int32*/, !1/*string*/)
... Comme vous pouvez le voir, un appel à Add
est le résultat, comme prévu. (On ne peut que supposer que le texte sur MSDN mentionné ci-dessus doit encore être mis à jour).
Jusqu'à présent, j'ai découvert un cas où cette différence est importante, à savoir avec l'excentrique System.Collections.Specialized.NameValueCollection
. Celle-ci permet à une clé de pointer vers plus d'une valeur. L'initialisation peut se faire de deux manières :
const String key = "sameKey";
const String value1 = "value1";
const String value2 = "value2";
var collection1 = new NameValueCollection
{
{key, value1},
{key, value2}
};
var collection2 = new NameValueCollection
{
[key] = value1,
[key] = value2
};
... Mais, en raison des différences dans la façon dont seul le premier appelle effectivement le NameValueCollection::Add(string, string)
les résultats diffèrent si l'on examine le contenu de chaque collection ;
collection1[key] = "value1,value2"
collection2[clef] = "valeur2
Je me rends compte qu'il y a un lien entre l'ancienne syntaxe et la IEnumerable
et comment le compilateur trouve l'interface Add
par convention d'appellation et ainsi de suite. Je suis également conscient des avantages que présente le fait que tout type d'indexeur soit soumis à la nouvelle syntaxe, comme cela a été évoqué dans le document cette réponse SO avant.
Peut-être s'agit-il de caractéristiques attendues, de votre point de vue, mais les implications ne m'avaient pas effleuré, et je suis curieux d'en savoir plus.
Je me demande donc s'il existe une source de documentation, sur MSDN ou ailleurs, qui clarifie cette différence de comportement liée au choix de la syntaxe. Je me demande également si vous connaissez d'autres exemples où ce choix peut avoir un tel impact, comme lors de l'initialisation d'un fichier de type NameValueCollection
.