Qual é a diferença entre essas duas variações de expressões inicializadoras de coleção?

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

Eu tenho usado o c # por um tempo, mas recentemente notei que o comportamento de um dos meus testes de unidade mudou dependendo de qual variação de expressão inicializador de coleção eu usei:

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

Até este ponto eu assumi que a segunda forma era apenas açúcar sintático e era semanticamente equivalente à primeira forma. No entanto, a alternância entre esses dois formulários resultou na passagem do meu teste de unidade com falha.

O código de exemplo abaixo demonstra isso:

 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 executo isso, a primeira atribuição funciona bem, mas a segunda resulta em um NullReferenceException .

Minha intuição é que nos bastidores o compilador está tratando essas duas expressões desta forma:

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

Essa suposição é exata?

1 Comments
Leon Barkan 07/31/2017
Isso ajudará você a: c-sharpcorner.com/article/…

1 Answers


Jon Skeet 07/31/2017.

Sim, sua suposição é correta. Se um inicializador de objeto tiver apenas:

{
    Property = { ... }
} 

ao invés de

{
    Property = expression
} 

então o setter para a propriedade não é usado - o getter é usado e, em seguida, o método Add é chamado ou as propriedades são definidas dentro do valor retornado. Assim:

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; 

Compare isso com:

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

o que equivale 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
Não deveria o equivalente a também nova coleção ou apenas adicionar?

Related questions

Hot questions

Language

Popular Tags