Wat is het verschil tussen deze twee varianten van de initialisatie-expressies van collecties?

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

Ik gebruik C # al een tijdje, maar merkte onlangs op dat het gedrag van een van mijn unit-tests veranderde, afhankelijk van de variatie van de collectie-initialisatie-expressie die ik gebruikte:

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

Tot dit moment nam ik aan dat de tweede vorm gewoon syntactische suiker was en semantisch equivalent was aan de eerste vorm. Het schakelen tussen deze twee formulieren resulteerde echter in het passeren van mijn testfout.

De onderstaande voorbeeldcode laat dit zien:

 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; }
} 

Wanneer ik dit NullReferenceException werkt de eerste toewijzing goed, maar de tweede resulteert in een NullReferenceException .

Mijn gevoel is dat achter de schermen de compiler deze twee uitdrukkingen als volgt behandelt:

 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); 

Is die veronderstelling juist?

1 Comments
Leon Barkan 07/31/2017
Dat zal je helpen: c-sharpcorner.com/article/...

1 Answers


Jon Skeet 07/31/2017.

Ja, uw aanname is juist. Als een object-initialisator slechts het volgende heeft:

{
    Property = { ... }
} 

liever dan

{
    Property = expression
} 

vervolgens wordt de setter voor de eigenschap niet gebruikt - de getter wordt gebruikt en vervolgens wordt de methode Add aangeroepen of worden eigenschappen binnen de geretourneerde waarde ingesteld. Zo:

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

is gelijk aan:

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

Vergelijk dat met:

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

wat gelijk is aan:

// 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
Moet het equivalent van de collectie ook niet nieuw zijn of voegt het gewoon toe?

Related questions

Hot questions

Language

Popular Tags