A tömbök esetén tárgyaltuk, hogy egy tömb elemeit létrehozhatjuk fordításkor is:
var array = new int[] { 1, 2, 3};
De ez a fajta szintaxis nem csak tömbök esetén működik, hanem a legtöbb C# kollekció esetén használható. De pontosan mit is jelent az, hogy a legtöbb kollekció esetén? Ennek a működése két feltételhez van kötve. Az első ilyen feltétel az, hogy a kollekciónak implementálnia kell az IEnumerable interfészt.
A második feltétel pedig az, hogy a kollekciónak rendelkeznie kell egy megfelelő szignatúrával rendelkező Add metódussal. Ez a metódus nem muszáj, hogy a kollekcióban legyen definiálva, lehet Extension methodként is definiálva. Az Add metódussal szemben annyi elvárás van, hogy a visszatérési típusa void legyen és legalább egy T típusú elemet kell fogadnia. A T típusának meg kell egyeznie a kollekció típusával.
A legalább szó nem véletlen a fenti esetben, mivel a Dictionary<Tkey, TValue> típus esetén két típussal dolgozik a kollekció. Ebből adódóan az Add metódus is két paraméteres és a paraméterek nem meglepő módon Tkey és TValue típusúak.
Ebből a leírásból sejthető, hogy ez a nyelvi funkció egy úgynevezett syntactic sugar, vagyis ez egy olyan nyelvi funkció, ami leegyszerűsíti a már meglévő funkciók használatát.
Vagyis amikor a következő módon hozunk létre egy listát vagy asszociatív tömböt:
var list = new List<int> { 1, 2, 3 };
var dictionary = new Dictionary<int, int>
{
{1, 1},
{2, 2},
{3, 3},
};
Akkor valójában a következő fog történni a háttérben:
var list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
var dictionary = new Dictionary<int, int>();
dictionary.Add(1, 1);
dictionary.Add(2, 2);
dictionary.Add(3, 3);
Kollekció inicializáló implementálása
Saját kollekciónk esetén is implementálhatjuk a szintaxist, viszonylag egyszerűen. Tételezzük fel, hogy van egy ilyen osztályunk:
public class Pont3D
{
public double X { get; }
public double Y { get; }
public double Z { get; }
public Pont3D(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}
}
Ezeket egy Pontok kollekcióban szeretnénk tárolni. A kollekció inicializáció szintaxishoz csupán egy IEnumerable<T> implementáció fog kelleni, illetve egy Add metódus a kollekciónkon:
public class Pontok : IEnumerable<Point3D>
{
private readonly List<Point3D> _points;
public Pontok()
{
_points = new List<Point3D>();
}
public void Add(double x, double y, double z)
{
_points.Add(new Point3D(x, y, z));
}
public IEnumerator<Point3D> GetEnumerator()
{
return _points.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Ezek után az elkészült kollekciónkat az alábbi módon már használatba is vehetjük:
var kocka = new Points
{
{ -1, -1, -1 },
{ -1, -1, 1 },
{ -1, 1, -1 },
{ -1, 1, 1 },
{ 1, -1, -1 },
{ 1, -1, 1 },
{ 1, 1, -1 },
{ 1, 1, 1 }
};