先看看MSDN对匿名方法的描述。
在2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。不过,本主题中有关匿名方法的信息同样也适用于 Lambda 表达式。有一种情况下,匿名方法提供了 Lambda 表达式中所没有的功能。匿名方法使您能够省略参数列表,这意味着可以将匿名方法转换为带有各种签名的委托。
匿名方法不是一个事先定义的方法,而是使用一个委托的代码块,在使用时,这和普通方法没有区别,但是匿名方法可以在一定程度上减少系统开销。
如何使用匿名方法?
下面举例说明如何利用匿名方法以及匿名方法的优点:
首先大家新建一个窗体工程,面板上放按钮,就用按钮的事件里面来看看匿名方法的使用吧。
1、常见用法
使用匿名方法很简单。只需要把匿名方法放在你通常放命名方法的关联语句里。下面例1里用委托执行了一个匿名方法:
示例1
private delegate void Example1Delegate(); private void button1_Click(object sender, EventArgs e) { Example1Delegate example = new Example1Delegate(delegate() { string showString = "例1:匿名方法基本用法。"; MessageBox.Show(showString); }); example(); }
结果图:
2、变量范围
任何在匿名方法里声明的变量的范围都不会超出匿名方法的代码块。但是,匿名方法具有访问它代码块之外的变量的能力,只要这些变量在匿名方法所使用的范围里。这些变量称为外部变量。下面示例2显示了匿名方法如何引用外部变量:
示例2
private delegate void Example2Delegate(); private void button2_Click(object sender, EventArgs e) { string stringFirst = "例2:"; string stringLast = "匿名方法使用外部变量。"; Example2Delegate example = new Example2Delegate( delegate() { string showString = string.Format("{0} {1}", stringFirst, stringLast); MessageBox.Show(showString); }); example(); }
结果图:
要注意的是,根据MSDN的文档,匿名方法里的ref和out参数无法被访问到。
3、参数的传递
可以将参数传递给匿名方法,方式就和处理引用命名方法参数的委托一样。下面的示例3说明这种类型的功能:
示例3
private delegate void Example3Delegate(string parameter1, string parameter2); private void button3_Click(object sender, EventArgs e) { string parameterString1 = "例3:"; string parameterString2 = "匿名方法参数传递。"; Example3Delegate example = new Example3Delegate( delegate(string string1, string string2) { string showString = string.Format("{0} {1}", string1, string2); MessageBox.Show(showString); }); example(parameterString1, parameterString2); }
结果图:
4、多个方法的关联
就和命名方法一样,将多个匿名方法与同一个委托进行关联是可能的。这在很多情况下会非常有用——首先想到的是把一个简单的处理程序添加给按钮的点击事件。下面的代码显示了一个委托,它同时带有与之相关联一个匿名方法和一个命名方法:
示例4
private delegate void Example4Delegate(string parameter1, string parameter2); private void button4_Click(object sender, EventArgs e) { string parameterString1 = "例4:"; string parameterString2 = "多个方法的关联。"; Example4Delegate example = new Example4Delegate( delegate(string string1, string string2) { string showString = string.Format("{0} {1}(匿名方法)", string1, string2); MessageBox.Show(showString); }); example += new Example4Delegate(Example4NamedMethod); example(parameterString1, parameterString2); } private void Example4NamedMethod(string parameter1, string parameter2) { string showString = string.Format("{0} {1}(命名方法)", parameter1, parameter2); MessageBox.Show(showString); }
结果图:
5、将匿名方法作为参数传递
就和命名方法一样,将匿名方法作为参数传递给函数是可能的。下面的代码说明了这种类型的功能,它将一个命名方法作为参数传递给了函数:
示例5
private delegate void Example5Delegate(string parameter1, string parameter2); private void button5_Click(object sender, EventArgs e) { Passit((Example5Delegate) delegate(string parameter1, string parameter2) { string showString = string.Format("{0} {1}(匿名方法)", parameter1, parameter2); MessageBox.Show(showString); }); Passit(Example5NamedMethod); } private void Example5NamedMethod(string parameter1, string parameter2) { string showString = string.Format("{0} {1}(命名方法)", parameter1, parameter2); MessageBox.Show(showString); } private void Passit(Example5Delegate example) { example("例5:", "匿名方法作为参数传递。"); }
结果图:
6、访问类成员
这是对上面例2的变量范围的扩展。
示例6
private delegate void Example6Delegate(); private string testString1; private string testString2; public string TestString1 { get { return testString1; } set { testString1 = value; } } public string TestString2 { get { return testString2; } set { testString2 = value; } } private void button6_Click(object sender, EventArgs e) { this.TestString1 = "例6:"; this.TestString2 = "访问类成员"; Example6Delegate example = new Example6Delegate( delegate { this.ShowCustomer(this.TestString1, this.TestString2); }); example(); this.TestString1 = "Example6:"; this.TestString2 = "Visitor Class Member."; example(); } private void ShowCustomer(string parameter1, string parameter2) { string showString = string.Format("{0} {1}", parameter1, parameter2); MessageBox.Show(showString); }
结果图:
要注意的是,这里两次调用了与匿名方法相关联的委托。你可能会发现一个很有趣的事情:在这些调用中,方法会输出两组不同的值。这是因为用在匿名方法里的外部变量在创建匿名方法的时候被引用。这意味着对这些变量的任何更改都会在匿名函数访问变量的时候被反映出来。
总结
本文已经说明如何使用匿名方法。给初学者理解和使用匿名方法提供一个引导的作用。