C#高级程序设计(六)——匿名方法
在 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
补充:软件开发 , C# ,