簡體   English   中英

什么是C#lambda的編譯? 一個堆棧框架,一個匿名類型的實例,或?

[英]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 =>有什么優先級,它們與匿名函數的關系是什么,以及一些高級的使用建議。

Lambda表達式(MSDN)

=>運營商(MSDN)

這里有些例子:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM