Hvad er forskellen mellem disse to variationer af indsamlingsinitieringsudtryk?

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

Jeg har brugt C # i et stykke tid, men har for nylig bemærket, at adfærden af ​​en af ​​mine enhedsprøver ændrede sig afhængigt af hvilken variant af indsamlingsinitieringsudtryk jeg brugte:

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

Indtil dette punkt antog jeg, at den anden form kun var syntaktisk sukker og var semantisk ækvivalent med den første formular. Men skift mellem disse to former resulterede i, at min failing unit test passerede.

Eksempelkoden nedenfor viser dette:

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

Når jeg kører dette, fungerer den første opgave fint, men det andet resulterer i en NullReferenceException .

Min tarmfølelse er, at bag kulisserne behandler kompilatoren disse to udtryk som dette:

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

Er den antagelse præcis?

1 Comments
Leon Barkan 07/31/2017
Det vil hjælpe dig: c-sharpcorner.com/article/...

1 Answers


Jon Skeet 07/31/2017.

Ja, din antagelse er korrekt. Hvis en objektinitiator kun har:

{
    Property = { ... }
} 

hellere end

{
    Property = expression
} 

så er setter til ejendommen ikke brugt - getter bruges, og så kaldes enten Add metoden eller egenskaber indstilles inden for den returnerede værdi. Så:

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

svarer til:

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

Sammenlign det med:

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

hvilket svarer til:

// 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
Skal det ikke ligestilles med at også nye samlingen eller tilføjer den bare?

Related questions

Hot questions

Language

Popular Tags