Qual è la differenza tra queste due varianti di espressioni di inizializzazione della raccolta?

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

Ho usato C # per un po ', ma di recente ho notato che il comportamento di uno dei miei test di unità è cambiato a seconda di quale variazione dell'espressione di inizializzazione della raccolta ho usato:

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

Fino a questo punto ho assunto che la seconda forma fosse solo zucchero sintattico e fosse semanticamente equivalente alla prima forma. Tuttavia, il passaggio tra queste due forme ha comportato il passaggio del test dell'unità in errore.

Il seguente codice di esempio lo dimostra:

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

Quando eseguo questo, il primo compito funziona bene ma il secondo risulta in una NullReferenceException .

Il mio istinto è che dietro le quinte il compilatore tratta queste due espressioni come segue:

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

Questa supposizione è accurata?

1 Comments
Leon Barkan 07/31/2017
Questo ti aiuterà: c-sharpcorner.com/article/...

1 Answers


Jon Skeet 07/31/2017.

Sì, la tua ipotesi è accurata. Se un inizializzatore di oggetti ha appena:

{
    Property = { ... }
} 

piuttosto che

{
    Property = expression
} 

quindi non viene utilizzato il setter per la proprietà: viene utilizzato il getter e quindi viene chiamato il metodo Add oppure le proprietà vengono impostate all'interno del valore restituito. Così:

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

è equivalente a:

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

Confrontalo con:

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

che è equivalente a:

// 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
Non dovrebbe l'equivalente di nuova anche la collezione o si aggiunge?

Related questions

Hot questions

Language

Popular Tags