Do czego służy metoda lambda expression Compile ()?

Staram się zrozumieć AST w C#. Zastanawiam się, co dokładnie Compile() Metoda z tego przykładu robi.

// Some code skipped    
Expression<Func<string, int, int, string>> data = Expression.Lambda<Func<string, int, int, string>>( 
        Expression.Call(s, typeof(string).GetMethod(“Substring”, new Type[] { typeof(int), typeof(int) }), a, b), 
        s, a, b 
    ); 
Func<string, int, int, string> fun = data.Compile(); 

Aby zapobiec nieporozumieniom, Rozumiem konstrukty Expression.Lambda i Expression.Call. Interesuje mnie metoda Compile(). Czy to w jakiś sposób produkuje prawdziwe MSIL? Mogę zobaczyć MSIL?

Author: jk_, 2011-11-14

3 answers

Interesuje mnie metoda Compile(). Czy to w jakiś sposób produkuje prawdziwe MSIL?

Tak. Metoda kompilacji uruchamia visitora nad body Blockiem lambda i generuje IL dynamicznie dla każdego podekspresji.

Jeśli jesteś zainteresowany nauką pluć IL siebie, zobacz Ten "Hello World" przykład jak używać Lightweight Codegen. (Zauważam, że jeśli jesteś w niefortunnej sytuacji konieczności korzystania z lekkiego Codegen w częściowo zaufanej appdomain wtedy rzeczy mogą się nieco dziwne w świecie z ograniczoną widocznością Pomiń; zobacz Shawn Farkas Artykuł na ten temat, jeśli to Cię interesuje.)

Mogę zobaczyć MSIL?
Tak, ale potrzebujesz specjalnego "wizualizera". Wizualizer, którego użyłem do debugowania Compile() podczas implementacji moich części można pobrać tutaj:

Http://blogs.msdn.com/b/haibo_luo/archive/2005/10/25/484861.aspx

 47
Author: Eric Lippert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-14 20:06:10

Wyrażenie przedstawia strukturę danych w postaci drzewa wyrażeń-używając Compile() to drzewo wyrażeń może być skompilowane do kodu wykonywalnego w postaci delegata (który jest wywołaniem" metody").

Po kompilacji możesz normalnie wywołać delegata - w twoim przykładzie delegat jest Func<string,int,int,string>. Takie podejście może być potrzebne, gdy dynamicznie tworzysz drzewo wyrażeń w oparciu o dane, które są dostępne tylko w czasie wykonywania z końcowym celem utworzenia i wykonanie odpowiedniego delegata.

Nie możesz zobaczyć "kodu" dla delegata. Najbliższe jest samo drzewo wyrażeń, na którym się opiera.

 8
Author: BrokenGlass,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-11-14 19:41:08

Odpowiedź na to jest teraz częściowo nieaktualna, ponieważ teraz tylko czasami dzieje się to, co się dzieje.

Kompilacja wyrażeń do IL wymaga refleksji.Emit, który nie jest dostępny przez cały czas, szczególnie z AOT. Tak więc w tych przypadkach zamiast kompilacji do IL wyrażenie jest "kompilowane" do listy obiektów reprezentujących instrukcje. Każda z tych instrukcji ma metodę Run, która powoduje, że wykonuje ona odpowiednie działanie, pracując na stosie wartości tak samo jak IL działa na stack. Metoda wywołująca Run Na tych obiektach może zostać zwrócona jako delegat.

Generalnie uruchamianie takiego delegata jest wolniejsze niż jitting IL, ale jest to jedyna opcja, gdy kompilowanie do IL nie jest dostępne, a krok kompilacji jest często szybszy, więc bardzo często całkowity czas kompilacji + uruchomienia jest krótszy w przypadku interpretera niż w przypadku IL dla wyrażeń jednorazowych.

Z tego powodu, w. NET Core jest teraz przeciążenie Compile, które zajmuje Boolean requesting interpretacja nawet w przypadku kompilacji do IL jest dostępna.

Wszystko to tworzy interesującą mieszankę języków; wyrażenia same w sobie są językiem, asemblacja jest napisana w C#, może kompilować się do IL, a interpretowane obiekty instrukcji stanowią czwarty język.

 5
Author: Jon Hanna,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-03 22:18:54