Mikä on ero näiden kahden kokoelman keräysalustaisen ilmaisujen välillä?

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

Olen käyttänyt C # hetken aikaa, mutta äskettäin huomasin, että jonkin yksikkökokeiluni käyttäytyminen muuttui riippuen siitä, mitä käyttämääni kokoelmasaloitin-ilmaisua oli käytetty:

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

Tähän mennessä oletin, että toinen muoto oli vain syntaktinen sokeri ja se vastasi semanttisesti ensimmäistä muotoa. Kuitenkin vaihto näiden kahden muodon välillä johti puuttuvan yksikkötestin kulkuun.

Alla oleva esimerkkikoodi osoittaa tämän:

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

Kun NullReferenceException tämän, ensimmäinen tehtävä toimii hyvin, mutta toinen tulos on NullReferenceException .

Minun suolen tunne on, että kulissien takana kääntäjä käsittelee näitä kahta ilmausta:

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

Onko tämä oletus tarkka?

1 Comments
Leon Barkan 07/31/2017

1 Answers


Jon Skeet 07/31/2017.

Kyllä, oletus on tarkka. Jos objektin alustalla on vain:

{
    Property = { ... }
} 

mielummin kuin

{
    Property = expression
} 

silloin kiinteistön asetusta ei käytetä - käytetään getter , ja sitten joko Add metodia tai asetetaan ominaisuudet palautetun arvon sisällä. Niin:

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

vastaa:

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

Vertaa sitä:

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

joka vastaa:

// 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
Eikö vastaava myös uusi kokoelma vai vain lisääkö se?

Related questions

Hot questions

Language

Popular Tags