C# Language
Initializers van de collectie
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.