Suche…


Bemerkungen

Die einzige Voraussetzung für die Initialisierung eines Objekts mit diesem syntaktischen Zucker ist, dass der Typ System.Collections.IEnumerable und die Add Methode implementiert. Obwohl wir es ein Auflistungsinitialisierer nennen, wird das Objekt muss nicht eine Sammlung.

Collection-Initialisierer

Initialisieren Sie einen Auflistungstyp mit Werten:

var stringList = new List<string>
{
    "foo",
    "bar",
};

Collection-Initialisierer sind syntaktischer Zucker für Add() Aufrufe. Der obige Code entspricht:

var temp = new List<string>();
temp.Add("foo");
temp.Add("bar");
var stringList = temp;

Beachten Sie, dass die Initialisierung mit einer temporären Variablen atomar erfolgt, um Race-Bedingungen zu vermeiden.

Für Typen, die in ihrer Add() Methode mehrere Parameter enthalten, schließen Sie die durch Kommas getrennten Argumente in geschweifte Klammern ein:

var numberDictionary = new Dictionary<int, string>
{
    { 1, "One" },
    { 2, "Two" },
};

Das ist äquivalent zu:

var temp = new Dictionary<int, string>();
temp.Add(1, "One");
temp.Add(2, "Two");
var numberDictionarynumberDictionary = temp;

C # 6 Index-Initialisierer

Beginnend mit C # 6 können Sammlungen mit Indexern initialisiert werden, indem der zuzuweisende Index in eckigen Klammern angegeben wird, gefolgt von einem Gleichheitszeichen und dem zuzuweisenden Wert.

Wörterbuch-Initialisierung

Ein Beispiel für diese Syntax mit einem Dictionary:

var dict = new Dictionary<string, int>
{
    ["key1"] = 1,
    ["key2"] = 50
};

Das ist äquivalent zu:

var dict = new Dictionary<string, int>();
dict["key1"] = 1;
dict["key2"] = 50

Die Syntax des Collection-Initialisierers vor C # 6 lautete:

var dict = new Dictionary<string, int>
{
    { "key1", 1 },
    { "key2", 50 }
};

Was würde entsprechen:

var dict = new Dictionary<string, int>();
dict.Add("key1", 1);
dict.Add("key2", 50);

Es gibt also einen signifikanten Unterschied in der Funktionalität, da die neue Syntax den Indexer des initialisierten Objekts verwendet, um Werte zuzuweisen, statt die Add() Methode zu verwenden. Dies bedeutet, dass für die neue Syntax nur ein öffentlich verfügbarer Indexer erforderlich ist und für jedes Objekt gilt, das über einen verfügt.

public class IndexableClass
{
    public int this[int index]
    {
        set 
        { 
            Console.WriteLine("{0} was assigned to index {1}", value, index);
        }
    }
}

var foo = new IndexableClass
{
    [0] = 10,
    [1] = 20
}

Dies würde ausgeben:

10 was assigned to index 0
20 was assigned to index 1

Auflistungsinitialisierer in benutzerdefinierten Klassen

Um eine Klassenunterstützungsauflistungsinitialisierer zu IEnumerable , muss sie die IEnumerable Schnittstelle implementieren und über mindestens eine Add Methode verfügen. Seit C # 6 kann jede Sammlung, die IEnumerable implementiert, um benutzerdefinierte Add Methoden erweitert werden, die Erweiterungsmethoden verwenden.

class Program
{
    static void Main()
    {
        var col = new MyCollection {
            "foo",
            { "bar", 3 },
            "baz",
            123.45d,
        };
    }
}

class MyCollection : IEnumerable
{
    private IList list = new ArrayList();

    public void Add(string item)
    {
        list.Add(item)
    }

    public void Add(string item, int count)
    {
        for(int i=0;i< count;i++) {
            list.Add(item);
        }
    }

    public IEnumerator GetEnumerator()
    {
        return list.GetEnumerator();
    }
}

static class MyCollectionExtensions
{
    public static void Add(this MyCollection @this, double value) => 
        @this.Add(value.ToString());
}

Collection-Initialisierer mit Parameter-Arrays

Sie können normale Parameter und Parameter-Arrays mischen:

public class LotteryTicket : IEnumerable{
    public int[] LuckyNumbers;
    public string UserName;

    public void Add(string userName, params int[] luckyNumbers){
        UserName = userName;
        Lottery = luckyNumbers;
    }
}

Diese Syntax ist jetzt möglich:

var Tickets = new List<LotteryTicket>{
    {"Mr Cool"  , 35663, 35732, 12312, 75685},
    {"Bruce"    , 26874, 66677, 24546, 36483, 46768, 24632, 24527},
    {"John Cena", 25446, 83356, 65536, 23783, 24567, 89337}
}

Sammlungsinitialisierer innerhalb des Objektinitialisierers verwenden

public class Tag
{
    public IList<string> Synonyms { get; set; }
}

Synonyms ist eine Eigenschaft der Sammlung. Wenn das Tag Objekt mit der Objektinitialisiersyntax erstellt wird, können Synonyms auch mit der Erfassungsinitialisiersyntax initialisiert werden:

Tag t = new Tag 
{
    Synonyms = new List<string> {"c#", "c-sharp"}
};

Die Auflistungseigenschaft kann nur gelesen werden und unterstützt weiterhin die Syntax der Auflistungsinitialisierer. Betrachten Sie dieses modifizierte Beispiel (die Eigenschaft " Synonyms jetzt einen privaten Setzer):

public class Tag
{
    public Tag()
    {
        Synonyms = new List<string>();
    }
    
    public IList<string> Synonyms { get; private set; }
}

Ein neues Tag Objekt kann folgendermaßen erstellt werden:

Tag t = new Tag 
{
    Synonyms = {"c#", "c-sharp"}
};

Dies funktioniert, da Collection-Initialisierer nur Syntaxzuweisungen bei Aufrufen von Add() . Hier wird keine neue Liste erstellt. Der Compiler generiert lediglich Aufrufe von Add() für das vorhandene Objekt.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow