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 表達式在 C# 中按值而不是按引用捕獲變數?的詳細內容。更多資訊請關注PHP中文網其他相關文章!