在C#中,Lambda表達式可以捕捉封閉作用域中的變數。當Lambda捕獲變數的引用時,對該變數的任何更改都將反映在Lambda中。這可能會導致意想不到的行為,如下面的程式碼片段所示:
<code class="language-C#">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>
執行此程式碼時,它會列印十次數字10。這是因為Lambda函數捕捉了變數i
的引用,當在for迴圈中i
遞增時,Lambda函數仍然看到更新後的值。
為了捕捉變數的副本而不是引用,可以使用以下語法:
<code class="language-C#">[=] () => { ... } // 捕获副本</code>
在此範例中,Lambda函數將擷取變數i
的副本,封閉作用域中對i
的任何變更都不會反映在Lambda函數中。
以下是一個修改後的範例,示範如何擷取副本:
<code class="language-C#">for (int i = 0; i < 10; i++) { int copy = i; // 创建一个局部副本 actions.Add(() => Console.WriteLine(copy)); }</code>
在這種情況下,Lambda函數將列印copy
的值,該值是在建立Lambda函數時i
的值的副本。
透過理解捕獲引用和捕獲副本之間的區別,您可以避免Lambda函數中的意外行為。
以上是C# Lambda 擷取中的引用與複製:何時會出現意外行為?的詳細內容。更多資訊請關注PHP中文網其他相關文章!