Na podstawie following question, znalazłem dziwne zachowanie kompilatora C#.C# nieparzystość kompilatora z delegowanymi konstruktorami
Poniżej jest ważny C#:
static void K() {}
static void Main()
{
var k = new Action(new Action(new Action(K))));
}
Co ja znajduję dziwny jest kompilator „dekonstrukcji” przekazany delegata.
Wyjście ILSpy jest następujący:
new Action(new Action(new Action(null, ldftn(K)), ldftn(Invoke)).Invoke);
Jak widać, to automatycznie zdecyduje się zastosować metodę delegata Invoke
. Ale dlaczego?
Tak jak jest, kod jest niejasny. Czy mamy potrójnie zawiniętego delegata (rzeczywistego), czy też wewnętrzny delegat właśnie "skopiował" do zewnętrznych (moja początkowa myśl).
pewnością jeśli intencją było jak kompilator emitowanego kod, należałoby napisać:
var k = new Action(new Action(new Action(K).Invoke).Invoke);
Podobne do dekompilacji kodu.
Czy ktoś może usprawiedliwić przyczynę tej "zaskakującej" transformacji?
Aktualizacja:
mogę myśleć tylko o jednej z możliwych przypadków użycia do tego przeznaczonych; konwersja typu delegata. Np .:
delegate void Baz();
delegate void Bar();
...
var k = new Baz(new Bar(new Action (K)));
Prawdopodobnie kompilator powinien wysłać ostrzeżenie, jeśli używane są te same typy delegatów.
Nie jest jasne, co masz na myśli przez „to wewnętrzna delegat prostu„skopiowane "do tych zewnętrznych" - czego dokładnie byś się spodziewał? Jedna instancja delegata? –
W interesie, gdzie zatrudniłbyś taką konstrukcję? Wygląda na to, że "potrójnie zapakowany delegat" zjadł nieostrożnego programistę na śniadanie ... – MoonKnight
@JonSkeet: Spodziewałem się, że będzie on bardziej podobny do "nowej akcji (a.Target, a.Method)" zamiast 'nowa Akcja (a.Invoke)'. IOW, bez pakowania. – leppie