Vad är skillnaden mellan dessa två variationer av uppsamlingsinitieringsuttryck?

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

Jag har använt C # ett tag men märkte nyligen att beteendet hos en av mina enhetstester har ändrats beroende på vilken variant av samlingsinitieringsuttryck som jag använde:

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

Fram till denna punkt antog jag att den andra formen bara var syntaktisk socker och var semantiskt ekvivalent med den första formen. Men byte mellan dessa två former resulterade i att mitt fel testades.

Exempelkoden nedan visar detta:

 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 jag kör detta fungerar den första uppgiften bra men den andra resulterar i en NullReferenceException .

Min känsla är att bakom kulisserna behandlar kompilatorn dessa två uttryck som detta:

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

Är det antagandet korrekt?

1 Comments
Leon Barkan 07/31/2017
Det hjälper dig: c-sharpcorner.com/article/...

1 Answers


Jon Skeet 07/31/2017.

Ja, ditt antagande är korrekt. Om en objektinitierare bara har:

{
    Property = { ... }
} 

hellre än

{
    Property = expression
} 

då används inte setter för egendomen - getter används, och då antingen Add metoden heter eller egenskaperna ställs in i returvärdet. Så:

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

är ekvivalent med:

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

Jämför det med:

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

vilket motsvarar:

// 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
Bör inte det likvärdiga med att även nya samlingen eller lägger den till?

Related questions

Hot questions

Language

Popular Tags