2016-04-27 2 views
3

Ich denke, es ist am besten jetzt den Code zu erhalten:Warum Sammlungsinitialisierer nicht mit Expression Body Eigenschaft zusammenarbeitet?

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

Offensichtlich ist die Main Methode 1 gedruckt werden soll, 2, 3, 4, 5, 6, aber er druckt 1, 2, 3 nur. Nach der Initialisierung ist foo.Ints2.Count gleich Null. Warum?

+3

Ihr 'Ints2' erstellt bei jedem Zugriff eine neue' Liste'. – PetSerAl

+0

@PetSerAl, ich grok, danke. –

Antwort

5

Es liegt daran, wie Sie die Eigenschaft Int2 definiert haben. Obwohl es in der Tat ein Getter ist, gibt es immer eine neue Liste zurück. Int1 ist eine schreibgeschützte Auto-Eigenschaft, daher wird immer dieselbe Liste zurückgegeben. Equivalent Compiler Magie Code entfernt für die Klasse Foo unter:

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

Wie Sie sehen können, alle mututations zu Ints2 verloren gehen, weil die Liste immer neu ist.

2

Ints2 => new List<int>(); ist die Abkürzung für Ints2 { get { return new List<int>(); } }. Bei jedem Lesen der Eigenschaft wird eine neue leere Liste zurückgegeben. Sie haben bereits die Korrektur: Ihr erstes Formular speichert die Liste in einem Feld.

2

Jedes Mal, wenn Sie auf Ihre Ints2-Eigenschaft zugreifen, wird die neue List<int> Instanz zurückgegeben.

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

Diese Linie bedeutet, dass das Trägerfeld durch die Eigenschaft zurückgeführt wird mit new List<int>() initialisiert.

Welche Auflistungsinitialisierer tun ist Aufruf Add Methode für jedes Element, so wird Ints1 3 Elemente (1, 2, 3).


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

Expression bodied bedeutet, dass Sie den Körper des getter definieren, etwa wie folgt:

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

Jedes Mal, wenn Sie Ints2 rufen eine neue Instanz zurückgegeben wird, das ist, warum Count Eigenschaft gibt zurück 0.

Verwandte Themen