Quelle est la différence entre ces deux variantes d'expressions d'initialisation de collection?

Tagc 09/16/2017. 1 answers, 803 views
c# collection-initializer

J'utilise C # depuis un moment, mais j'ai récemment remarqué que le comportement de l'un de mes tests unitaires changeait en fonction de la variation de l'expression d'initialisation de collection utilisée:

  • var object = new Class { SomeCollection = new List { 1, 2, 3 } };
  • var object = new Class { SomeCollection = { 1, 2, 3 } };

Jusqu'à ce point j'ai supposé que la deuxième forme était juste du sucre syntaxique et était sémantiquement équivalente à la première forme. Cependant, la commutation entre ces deux formes a entraîné la réussite de mon test d'unité défaillante.

L'exemple de code ci-dessous montre ceci:

 void Main()
{
    var foo1 = new Foo { Items = new List { 1, 2, 3} };
    var foo2 = new Foo { Items = { 1, 2, 3 } };

    foo1.Dump();
    foo2.Dump();
}

class Foo
{
    public List Items { get; set; }
} 

Lorsque NullReferenceException ceci, la première affectation fonctionne bien, mais la seconde entraîne une NullReferenceException .

Mon intuition est que dans les coulisses, le compilateur traite ces deux expressions comme suit:

 var foo1 = new Foo();
foo1.Items = new List { 1, 2, 3 }; 

var foo2 = new Foo();
foo2.Items.Add(1);
foo2.Items.Add(2);
foo2.Items.Add(3); 

Cette hypothèse est-elle exacte?

1 Comments
Leon Barkan 07/31/2017
Cela vous aidera: c-sharpcorner.com/article / ...

1 Answers


Jon Skeet 07/31/2017.

Oui, votre hypothèse est exacte. Si un initialiseur d'objet a juste:

{
    Property = { ... }
} 

plutôt que

{
    Property = expression
} 

alors le setter pour la propriété n'est pas utilisé - le getter est utilisé, puis la méthode Add est appelée, ou les propriétés sont définies dans la valeur retournée. Alors:

var foo = new Foo
{
    Collection = { 1 }
    Property =
    {
        Value = 1
    }
}; 

est équivalent à:

// Only the *getters* for Collection and Property are called
var foo = new Foo();
foo.Collection.Add(1);
foo.Property.Value = 1; 

Comparez cela avec:

var foo = new Foo
{
    Collection = new List { 1 },
    Property = new Bar { Value = 1 }
}; 

ce qui équivaut à:

// The setters for Collection and Property are called
var foo = new Foo();
foo.Collection = new List { 1 };
foo.Property = new Bar { Value = 1 }; 
1 comments
1 Ash Burlaczenko 07/31/2017
L'équivalent d'une nouvelle collection ne devrait-il pas être ajouté ou est-ce que cela ne fait qu'ajouter?

Related questions

Hot questions

Language

Popular Tags