5 votes

Différence entre les syntaxes des initialisateurs de collection

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 .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X