Przykład:
public void Test()
{
List ar1 = new List { new Point(3, 4), new Point(5, 6) };
ar1.ToString();
}
Kod IL:
.method public hidebysig instance void Test() cil managed
{
.maxstack 4
.locals init (
[0] class [mscorlib]System.Collections.Generic.List`1<valuetype [System.Drawing]System.Drawing.Point> ar1,
[1] class [mscorlib]System.Collections.Generic.List`1<valuetype [System.Drawing]System.Drawing.Point> <>g__initLocal2d5)
L_0000: newobj instance void [mscorlib]System.Collections.Generic.List`1<valuetype [System.Drawing]System.Drawing.Point>::.ctor()
L_0005: stloc.1
L_0006: ldloc.1
L_0007: ldc.i4.3
L_0008: ldc.i4.4
L_0009: newobj instance void [System.Drawing]System.Drawing.Point::.ctor(int32, int32)
L_000e: callvirt instance void [mscorlib]System.Collections.Generic.List`1<valuetype [System.Drawing]System.Drawing.Point>::Add(!0)
L_0013: ldloc.1
L_0014: ldc.i4.5
L_0015: ldc.i4.6
L_0016: newobj instance void [System.Drawing]System.Drawing.Point::.ctor(int32, int32)
L_001b: callvirt instance void [mscorlib]System.Collections.Generic.List`1<valuetype [System.Drawing]System.Drawing.Point>::Add(!0)
L_0020: ldloc.1
L_0021: stloc.0
L_0022: ldloc.0
L_0023: callvirt instance string [mscorlib]System.Object::ToString()
L_0028: pop
L_0029: ret
}
Widzimy, że inicjalizacja odbywa się poprzez wywołanie metody
Add
obiektu. Cała konstrukcja listy odbywa się poprzez zmienną tymczasową, dzięki czemu proces ten jest atomowy. Zauważmy też że podczas konstrukcji obiektu nie musimy pisać
new List()
. Jakie warunki musi spełniać klasa, by użycie takiej inicjalizacji było możliwe? Warunki są dwa. Po pierwsze klasa musi implementować interfejs
System.Collections.IEnumerable
. Po drugie musi zawierać metodę
Add()
. Czemu samo posiadanie przez klase metody
Add()
nie wystarczy nie wiem. Skoro już dano takie ograniczenie o wiele rozsądniejsze było by wymaganie implementacji interfejsu
ICollection
, który wymaga implementacji metody
Add()
. Przykład własnej klasy, która pozwala nam na skróconą inicjalizację kolekcji:
class TestA : IEnumerable
{
public void Add(int a)
{
}
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
public void Test()
{
TestA testa = new TestA { 1, 2 };
testa.ToString();
}
Wariacje na temat typu parametru metody
Add()
sobie odpuścimy. Wygląda na to, że musi istnieć bezpośrednia konwersja pomiędzy parametrem metody, a składnikiem inicjalizacji. Teraz przyjrzyjmy się bliżej metodzie
Add()
. Oto przykład dla metody o dwóch parametrach:
class TestB : IEnumerable
{
public void Add(int a, int b)
{
}
public IEnumerator GetEnumerator()
{
throw new NotImplementedException();
}
}
public void Test()
{
TestB testb = new TestB { {1, 2}, {2, 3} };
testb.ToString();
}
Jest o tyle ważne, że podobnie jak listę możemy inicjalizować słownik:
public void Test()
{
Dictionary dict = new Dictionary() { { Color.Red, "Red" } };
dict.ToString();
}
Brak komentarzy:
Prześlij komentarz