Zoeken…


Opmerkingen

De enige vereiste voor een object dat moet worden geïnitialiseerd met behulp van deze syntactische suiker, is dat het type System.Collections.IEnumerable en de methode Add implementeert. Hoewel we noemen een verzameling initialiseerder, is het object niet aan een collectie.

Collectie initializers

Initialiseer een verzamelingstype met waarden:

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

Collectie-initializers zijn syntactische suiker voor Add() -aanroepen. Bovenstaande code is gelijk aan:

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

Merk op dat de initialisatie atoom gebeurt met behulp van een tijdelijke variabele, om raceomstandigheden te voorkomen.

Voor typen die meerdere parameters bieden in hun Add() -methode, plaatst u de door komma's gescheiden argumenten tussen accolades:

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

Dit komt overeen met:

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

C # 6 Indexinitializers

Beginnend met C # 6, kunnen collecties met indexers worden geïnitialiseerd door de toe te kennen index op te geven tussen vierkante haken, gevolgd door een is-teken, gevolgd door de waarde die moet worden toegewezen.

Woordenboekinitialisatie

Een voorbeeld van deze syntaxis met behulp van een woordenboek:

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

Dit komt overeen met:

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

De syntaxis van de collectie-initialisatie om dit te doen vóór C # 6 was:

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

Welke zou overeenkomen met:

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

Er is dus een aanzienlijk verschil in functionaliteit, omdat de nieuwe syntaxis de indexer van het geïnitialiseerde object gebruikt om waarden toe te wijzen in plaats van de methode Add() . Dit betekent dat de nieuwe syntaxis alleen een openbaar beschikbare indexer vereist en werkt voor elk object dat er een heeft.

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
}

Dit zou het volgende opleveren:

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

Collectie-initializers in aangepaste klassen

Om een initialisatie van een klassenondersteuning te ondersteunen, moet het een IEnumerable interface implementeren en minstens één Add methode hebben. Sinds C # 6 kan elke verzameling die IEnumerable implementeert, worden uitgebreid met aangepaste methoden voor het Add van uitbreidingsmethoden.

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

Initializers voor verzameling met parameterarrays

U kunt normale parameters en parameterarrays combineren:

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

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

Deze syntaxis is nu mogelijk:

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

Collectie-initialisatie gebruiken in object-initialisatie

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

Synonyms is een eigenschap van het verzamelingstype. Wanneer het Tag object wordt gemaakt met de syntaxis van de initialisatie van objecten, kan Synonyms ook worden geïnitialiseerd met de syntaxis van de initialisatie van de collectie:

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

De eigenschap collection kan alleen worden gelezen en ondersteunt nog steeds de syntaxis van de initialisatie van de collectie. Beschouw dit gewijzigde voorbeeld (de eigenschap Synonyms heeft nu een privésetter):

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

Een nieuw Tag object kan als volgt worden gemaakt:

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

Dit werkt omdat collectie-initializers alleen maar syntatische suiker zijn boven oproepen naar Add() . Er wordt hier geen nieuwe lijst gemaakt, de compiler genereert alleen aanroepen naar Add() op het bestaande object.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow