C# Language
Inizializzatori di raccolta
Ricerca…
Osservazioni
L'unico requisito per l'inizializzazione di un oggetto utilizzando questo zucchero sintattico è che il tipo implementa System.Collections.IEnumerable
e il metodo Add
. Sebbene lo chiamiamo inizializzatore di una raccolta, l'oggetto non deve essere una raccolta.
Inizializzatori di raccolta
Inizializza un tipo di raccolta con valori:
var stringList = new List<string>
{
"foo",
"bar",
};
Gli inizializzatori della raccolta sono zucchero sintattico per le chiamate Add()
. Sopra il codice è equivalente a:
var temp = new List<string>();
temp.Add("foo");
temp.Add("bar");
var stringList = temp;
Si noti che l'intializzazione viene eseguita atomicamente utilizzando una variabile temporanea, per evitare condizioni di competizione.
Per i tipi che offrono più parametri nel loro metodo Add()
, racchiudi gli argomenti separati da virgola in parentesi graffe:
var numberDictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
};
Questo è equivalente a:
var temp = new Dictionary<int, string>();
temp.Add(1, "One");
temp.Add(2, "Two");
var numberDictionarynumberDictionary = temp;
Inizializzatori dell'indice C # 6
A partire da C # 6, le raccolte con indicizzatori possono essere inizializzate specificando l'indice da assegnare tra parentesi quadre, seguito da un segno di uguale, seguito dal valore da assegnare.
Inizializzazione del dizionario
Un esempio di questa sintassi utilizzando un dizionario:
var dict = new Dictionary<string, int>
{
["key1"] = 1,
["key2"] = 50
};
Questo è equivalente a:
var dict = new Dictionary<string, int>();
dict["key1"] = 1;
dict["key2"] = 50
La sintassi di inizializzazione della raccolta per eseguire questa operazione prima di C # 6 era:
var dict = new Dictionary<string, int>
{
{ "key1", 1 },
{ "key2", 50 }
};
Quale corrisponderebbe a:
var dict = new Dictionary<string, int>();
dict.Add("key1", 1);
dict.Add("key2", 50);
Quindi c'è una differenza significativa nella funzionalità, poiché la nuova sintassi usa l' indicizzatore dell'oggetto inizializzato per assegnare valori invece di usare il suo metodo Add()
. Ciò significa che la nuova sintassi richiede solo un indicizzatore pubblicamente disponibile e funziona per qualsiasi oggetto che ne ha uno.
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
}
Ciò produrrebbe:
10 was assigned to index 0
20 was assigned to index 1
Inizializzatori di raccolta in classi personalizzate
Per creare un inizializzatore della raccolta del supporto classe, deve implementare l'interfaccia IEnumerable
e avere almeno un metodo Add
. Dal momento che C # 6, qualsiasi raccolta attuare IEnumerable
può essere esteso con personalizzati Add
metodi che utilizzano metodi di estensione.
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());
}
Inizializzatori di raccolta con array di parametri
È possibile combinare parametri normali e array di parametri:
public class LotteryTicket : IEnumerable{
public int[] LuckyNumbers;
public string UserName;
public void Add(string userName, params int[] luckyNumbers){
UserName = userName;
Lottery = luckyNumbers;
}
}
Questa sintassi è ora possibile:
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}
}
Utilizzo di inizializzatore di raccolta nell'inizializzatore dell'oggetto
public class Tag
{
public IList<string> Synonyms { get; set; }
}
Synonyms
è una proprietà del tipo di raccolta. Quando l'oggetto Tag
viene creato utilizzando la sintassi di inizializzazione dell'oggetto, i Synonyms
possono anche essere inizializzati con la sintassi di inizializzazione della raccolta:
Tag t = new Tag
{
Synonyms = new List<string> {"c#", "c-sharp"}
};
La proprietà della raccolta può essere in sola lettura e supporta ancora la sintassi di inizializzazione della raccolta. Considera questo esempio modificato (la proprietà Synonyms
ora ha un setter privato):
public class Tag
{
public Tag()
{
Synonyms = new List<string>();
}
public IList<string> Synonyms { get; private set; }
}
Un nuovo oggetto Tag
può essere creato in questo modo:
Tag t = new Tag
{
Synonyms = {"c#", "c-sharp"}
};
Funziona perché gli inizializzatori della raccolta sono solo zucchero sintattico sulle chiamate a Add()
. Non è stato creato alcun nuovo elenco qui, il compilatore sta solo generando chiamate a Add()
sull'oggetto che sta uscendo.