首頁 >後端開發 >C++ >如何確保 Lambda 表達式在 C# 中按值而不是按引用捕獲變數?

如何確保 Lambda 表達式在 C# 中按值而不是按引用捕獲變數?

Patricia Arquette
Patricia Arquette原創
2025-01-19 00:14:11239瀏覽

How Do I Ensure Lambda Expressions Capture Variables by Value Instead of by Reference in C#?

C# Lambda 表達式中的值捕獲與引用捕獲

在 C# 中,Lambda 表達式可以捕捉封閉作用域中的變數。預設情況下,這些捕獲是透過引用進行的,這意味著 Lambda 表達式存取與原始變數相同的記憶體位置。然而,在某些情況下,您可能希望捕獲變數的副本而不是引用。

問題:

考慮以下 C# 程式碼:

<code class="language-csharp">class Program
{
    delegate void Action();
    static void Main(string[] args)
    {
        List<Action> actions = new List<Action>();

        for (int i = 0; i < 10; i++)
            actions.Add(() => Console.WriteLine(i));

        foreach (Action a in actions)
            a();
    }
}</code>

問題描述:

預期輸出是每個 Lambda 表達式在迭代列表時列印其對應的 i 值。但是,在本例中,所有 Lambda 表達式都會列印值 10,這表示它們都引用相同的變數 i。這是因為 Lambda 表達式透過引用捕獲 i。

解:

為了強制 Lambda 表達式擷取 i 的副本,一個解決方案是先建立一個局部副本:

<code class="language-csharp">for (int i = 0; i < 10; i++)
{
    int copy = i; // 创建局部副本
    actions.Add(() => Console.WriteLine(copy));
}</code>

解釋:

透過在循環中建立 i 的局部副本,Lambda 表達式會擷取 copy 的值,該值是在該時間點原始 i 的副本。這確保每個 Lambda 表達式都有其自身的值副本,並將列印對應的 i 值。

區別:

透過引用捕捉和透過值捕捉變數的差異在於它們與 Lambda 表達式外部變數的交互方式。

  • 透過引用捕獲: Lambda 表達式直接存取原始變數的記憶體位置。對 Lambda 表達式外部變數所做的任何變更都會反映在 Lambda 表達式中,反之亦然。
  • 透過值擷取: Lambda 表達式在擷取時存取原始變數值的副本。對 Lambda 表達式外部變數所做的任何變更都不會影響 Lambda 表達式擷取的副本,且 Lambda 表達式的值保持不變。

以上是如何確保 Lambda 表達式在 C# 中按值而不是按引用捕獲變數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn