上一篇:http://www.BkJia.com/kf/201208/150595.html
在 2.0 之前的C# 版本中,聲明委托的唯一方法是使用命名方法。 C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表達式取代了匿名方法,作為編寫內聯代碼的首選方式。 不過,本主題中有關匿名方法的信息同樣也適用於 Lambda 表達式。 有一種情況下,匿名方法提供了 Lambda 表達式中所沒有的功能。 您可使用匿名方法來忽略參數列表。 這意味著匿名方法可轉換為具有各種簽名的委托。 這對於 Lambda 表達式來說是不可能的。
匿名方法提供了用代碼塊聲明委托對象的功能,如果使用匿名方法,則不必創建單獨的方法,因此減少了實例化委托所需的編碼系統開銷。
[csharp]
void StartThread()
{
System.Threading.Thread t1 = new System.Threading.Thread
(delegate()
{
System.Console.Write("Hello, ");
System.Console.WriteLine("World!");
});
t1.Start();
}
一、忽略代理參數
如果代理的實現裡不依賴於它的參數,你可以去掉整個參數列表,只使用delegate關鍵字和語句塊。
[csharp]
button.MouseClick += delegate { Console.WriteLine("LogMouse"); };
二、捕獲外部變量
如果局部變量和參數的作用范圍包含匿名方法聲明,則該局部變量和參數稱為外部變量,如果外部變量被其中的匿名方法使用,則該外部變量稱為捕獲外部變量或簡稱為捕獲變量。例如,下面代碼段中的 n 即是一個捕獲變量:
[csharp]
int n = 0;
Del d = delegate() { System.Console.WriteLine("Copy #:{0}", ++n); };
與局部變量不同,捕獲變量的生命周期一直持續到任何引用該捕獲變量的代理對象符合垃圾回收條件為止。這一點是捕獲外部變量的最關鍵點。例如:
[csharp]
List<MethodInvoker> list = new List<MethodInvoker>();
for (int index = 0; index < 5; index++)
{
int counter = index * 10;
list.Add(delegate
{
Console.WriteLine(counter);
counter++;
});
}
foreach (MethodInvoker t in list)
{
t();
}
list[0]();
list[0]();
list[0]();
list[1]();
Output:
0
10
20
30
40
1
2
3
11
[csharp] view plaincopy
List<MethodInvoker> list = new List<MethodInvoker>();
for (int index = 0; index < 5; index++)
{
list.Add(delegate
{
Console.WriteLine(index);
index++;
});
}
foreach (MethodInvoker t in list)
{
t();
}
list[0]();
list[0]();
list[0]();
list[1]();
Output:
5
6
7
8
9
10
11
12
13