讓我們看看下面的代碼示例。有一個代表串列,然后兩個實體按順序插入到該串列中。
class Client
{
delegate void ActionListener(string message);
public static void Main()
{
List<ActionListener> _actionListenerList = new List<ActionListener>();
_actionListenerList.Add((message) => Console.WriteLine(message));
_actionListenerList.Add((message) => Console.WriteLine(message));
if (_actionListenerList[0].Equals(_actionListenerList[1]))
{
Console.WriteLine("Two Delegates are equal");
}
else
{
Console.WriteLine("Two Delegates did not match");
}
}
}
輸出:
兩個代表不匹配
現在,如果我們修改代碼并使用 for 回圈在串列中添加委托,則輸出完全不同。
class Client
{
delegate void ActionListener(string message);
public static void Main()
{
List<ActionListener> _actionListenerList = new List<ActionListener>();
for (int i = 0; i < 2; i )
{
_actionListenerList.Add((message) => Console.WriteLine(message));
}
if (_actionListenerList[0].Equals(_actionListenerList[1]))
{
Console.WriteLine("Two Delegates are equal");
}
else
{
Console.WriteLine("Two Delegates did not match");
}
}
}
輸出:
兩個代表是平等的
我想,我的問題不需要進一步解釋 - 為什么使用 for 回圈后會產生差異?
uj5u.com熱心網友回復:
請注意,語言規范 允許此處的兩個 lambda 運算式都轉換為相同的委托實體:
_actionListenerList.Add((message) => Console.WriteLine(message));
_actionListenerList.Add((message) => Console.WriteLine(message));
允許(但不要求)將具有相同(可能為空)捕獲的外部變數實體集的語意相同匿名函式轉換為相同的委托型別,以回傳相同的委托實體。
因此,您可能會看到在編譯器上創建了兩個不同的委托實體,但在另一個編譯器上,作為優化,可以將 lambda 轉換為相同的委托實體。
為了確保您絕對擁有不同的委托實體(盡管我認為這很少有用),您可以在回圈內捕獲一個區域變數(由 Jon Skeet 建議)。現在 lambdas 沒有“相同的一組捕獲的區域變數”:
for (int i = 0; i < 2; i )
{
int x = 0;
_actionListenerList.Add(
(message) => {
Console.WriteLine(message);
_ = x;
}
);
}
uj5u.com熱心網友回復:
_actionListenerList.Add((message) => Console.WriteLine(message));
_actionListenerList.Add((message) => Console.WriteLine(message));
在這個版本中,有兩個不同的功能。一個 lambda 只是一個單行函式,所以如果你有兩個,那么每個人的委托將不相等。
實際上就好像你寫了:
_actionListenerList.Add(Lambda1);
_actionListenerList.Add(Lambda2);
void Lambda1(string message)
{
Console.WriteLine(message);
}
void Lambda2(string message)
{
Console.WriteLine(message);
}
for (int i = 0; i < 2; i )
{
_actionListenerList.Add((message) => Console.WriteLine(message));
}
在這個版本中,只有一個函式,所以每個委托都參考同一個函式。
就像你寫的
for (int i = 0; i < 2; i )
{
_actionListenerList.Add(Lambda1);
}
void Lambda1(string message)
{
Console.WriteLine(message);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/371690.html
上一篇:c#Json獲取所有父子值
