2016-04-27 5 views
3

私はそれが、今のコードを表示するのが最善だと思う:コレクション初期化子が式の本体プロパティと一緒に機能していないのはなぜですか?

class Foo 
{ 
    public ICollection<int> Ints1 { get; } = new List<int>(); 

    public ICollection<int> Ints2 => new List<int>(); 
} 

class Program 
{ 
    private static void Main(string[] args) 
    { 
     var foo = new Foo 
     { 
      Ints1 = { 1, 2, 3 }, 
      Ints2 = { 4, 5, 6 } 
     }; 

     foreach (var i in foo.Ints1) 
      Console.WriteLine(i); 

     foreach (var i in foo.Ints2) 
      Console.WriteLine(i); 
    } 
} 

明らかMain方法が唯一、1、2、3、4、5を印刷6が、それは1を出力し、2、3べきです。初期化後、foo.Ints2.Countはゼロに等しくなります。どうして?

+3

あなたの 'Ints2'はすべてのアクセスで新しい' List'を作成します。 – PetSerAl

+0

@PetSerAl、私grok、ありがとう。 –

答えて

5

これは、プロパティInt2の定義方法によるものです。それは確かにゲッターですが、常に新しいリストを返しています。 Int1は読み取り専用の自動プロパティなので、常に同じリストを返します。下記のFooクラスのために取り外さ同等のコンパイラマジックコード:

class Foo 
{ 
    private readonly ICollection<int> ints1 = new List<int>(); 
    public ICollection<int> Ints1 { get { return this.ints1; } } 

    public ICollection<int> Ints2 { get { return new List<int>(); } } 
} 

あなたが見ることができるように、リストは常に新しいものであるため、INTS2へのすべてのmututationsは失われます。

2

Ints2 => new List<int>();は、Ints2 { get { return new List<int>(); } }の略です。プロパティが読み取られるたびに、新しい空のリストが返されます。すでに修正があります:最初のフォームはリストをフィールドに保存します。

2

Ints2プロパティにアクセスするたびに、新しいList<int>インスタンスが返されます。

1
public ICollection<int> Ints1 { get; } = new List<int>(); 

この行は、プロパティによって返さバッキングフィールドはnew List<int>()で初期化されることを意味します。何コレクション初期化子

は、各要素のための呼び出しAdd方法なので、Ints1は3つの要素を持つことになります(123)。


public ICollection<int> Ints2 => new List<int>(); 

発現は、あなたが、このような何かgetterの本体を定義していることを意味ボディ:なぜCountプロパティが返す

public ICollection<int> Ints2 => new List<int>(); 
{ 
    get 
    { 
     return new List<int>(); 
    } 
} 

新しいインスタンスが返されInts2を呼び出すたびに、thatsの0

関連する問題