コレクション初期化式のこれらの2つのバリエーションの違いは何ですか?

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

私はしばらくの間C#を使用していましたが、最近私の単体テストの動作は、私が使用したコレクション初期化式のバリエーションに応じて変化しています。

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

この時点まで、私は第2の形式が構文的な砂糖であり、第1の形式と意味的に同等であると仮定しました。 しかし、これらの2つの形式を切り替えると、失敗した単体テストになりました。

以下のサンプルコードはこれを示しています:

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

これを実行すると、最初の割り当ては正常に動作しますが、2番目の割り当てはNullReferenceExceptionます。

私の直感は、舞台裏ではコンパイラが次の2つの表現をこのように扱っていることです。

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

その仮定は正確ですか?

1 Comments
Leon Barkan 07/31/2017
それはあなたを助けるでしょう: c-sharpcorner.com/article / ...

1 Answers


Jon Skeet 07/31/2017.

はい、あなたの前提は正確です。 オブジェクトイニシャライザに次のものがある場合:

{
    Property = { ... }
} 

のではなく、

{
    Property = expression
} 

プロパティのsetterは使用されません。 getterが使用され、 Addメソッドが呼び出されるか、戻り値内でプロパティーが設定されます。 そう:

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

次のものと同等です。

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

それと比較する:

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

これは以下と同等です:

// 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
新しいコレクションに相当するはずではないですか?

Related questions

Hot questions

Language

Popular Tags