[英]What are C# lambda's compiled into? A stackframe, an instance of an anonymous type, or?
什么是C#lambda的編譯? 一個堆棧框架,一個匿名類型的實例,或?
我讀過這個問題 。 這主要回答“為什么”在使用隱式類型功能時不能使用lambda。 但是,這個問題的目的是回答編譯器生成的構造實際執行lambda的代碼。 它是一個匿名類型的方法調用(類似於在Java中實現接口的匿名類型嗎?),還是只是一個堆棧框架,它引用了閉合變量並接受了參數簽名? 有些lambda不會關閉任何東西 - 因此編譯中有兩個不同的結果輸出。
假設你的意思是“作為委托”,那么它仍然取決於:p如果它捕獲任何變量(包括“this”,這可能是隱含的)那么這些變量實際上是作為編譯器生成的類型的字段實現的(不公開任何地方),語句體成為該捕獲類的方法。 如果有多個捕獲級別,則外捕獲也是內捕獲類的一個字段。 但基本上:
int i = ...
Func<int,int> func = x => 2*x*i;
就好像;
var capture = new SecretType();
capture.i = ...
Func<int,int> func = capture.SecretMethod;
哪里:
class SecretType {
public int i;
public int SecretMethod(int x) { return 2*x*i; }
}
這與“匿名方法”相同,但語法不同。
請注意,不捕獲狀態的方法可以實現為沒有捕獲類的靜態方法。
另一方面,表達樹......解釋起來比較棘手:p
但是(我沒有編譯器,所以請耐心等待):
int i = ...
Expression<Func<int,int>> func = x => 2*x*i;
是這樣的:
var capture = new SecretType();
capture.i = ...
var p = Expression.Parameter("x", typeof(int));
Expression<Func<int,int>> func = Expression.Lambda<Func<int,int>>(
Expression.Multiply(
Expression.Multiply(Expression.Constant(2),p),
Expression.PropertyOrField(Expression.Constant(capture), "i")
), p);
(除了使用不存在的“memberof”構造,因為編譯器可以作弊)
表達式樹很復雜,但可以解構和檢查 - 例如轉換為TSQL。
Lambda表達式確實是匿名函數,但具有更多功能。 這兩篇由MSDN撰寫的文章有很多關於lambda表達式的信息,如何使用它們,operator =>
有什么優先級,它們與匿名函數的關系是什么,以及一些高級的使用建議。
這里有些例子:
public class C
{
private int field = 0;
public void M()
{
int local = 0;
Func<int> f1 = () => 0;
// f1 is a delegate that references a compiler-generated static method in C
Func<int> f2 = () => this.field;
// f2 is a delegate that references a compiler-generated instance method in C
Func<int> f3 = () => local;
// f3 is a delegate that references an instance method of a compiler-generated nested class in C
}
}
lambda表達式是一種代替委托代理的未命名方法。 編譯器將其轉換為:
Expression<TDelegate>
類型的表達式樹 ,表示可遍歷對象模型中的代碼。 這允許在運行時解釋lambda表達式。 因此,編譯器解決了將表達式代碼移動到私有方法中的lambda表達式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.