在 2.0 之前的 C# 版本中,声明委托的唯一方法是使用命名方法。C# 2.0 引入了匿名方法,而在 C# 3.0 及更高版本中,Lambda 表达式取代了匿名方法,作为编写内联代码的首选方式。不过,本主题中有关匿名方法的信息同样也适用于 Lambda 表达式。有一种情况下,匿名方法提供了 Lambda 表达式中所没有的功能。匿名方法使您能够省略参数列表,这意味着可以将匿名方法转换为带有各种签名的委托。这对于 Lambda 表达式来说是不可能的。
要将代码块传递为委托参数,创建匿名方法则是唯一的方法。这里是两个示例:
例1:
在Form上拖放一个Button按钮
书写相关代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WinApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//创建click事件的处理。+=合并委托。将代码块传递为委托参数
button1.Click += delegate(System.Object o, System.EventArgs e2)
{
System.Windows.Forms.MessageBox.Show("你好,委托!");
};
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("委托示例");
}
}
}
运行结果,先显示“委托示例”,再显示“你好,委托”
|
|
例2:
//声明委托
delegate void Printer(string s);
//中间代码略,完整代码看最后示例
//利用匿名方法,实例化一个委托
Printer p2=delegate(string s)
{
Console.WriteLine(s);
};
p2("我是中国人,我爱编程。(使用匿名方法)");
备注
匿名方法的参数的范围是“匿名方法块”。
如果目标在块外部,那么,在匿名方法块内使用跳转语句(如 goto、break 或 continue)是错误的。如果目标在块内部,在匿名方法块外部使用跳转语句(如 goto、break 或 continue)也是错误的。
如果局部变量和参数的范围包含匿名方法声明,则该局部变量和参数称为该匿名方法的“外部”变量。例如,下面代码段中的 age 即是一个外部变量:
例:
delegate void Del();
//中间代码略,完整代码看最后示例
//利用该匿名方法的“外部”变量n
int age = 20;
Del p3 = delegate()
{
Console.WriteLine("年龄:{0}", age);
};
p3();
输出:年龄:20
与局部变量不同,捕获变量的生命周期一直持续到引用该匿名方法的委托符合垃圾回收的条件为止。对 age 的引用是在创建该委托时捕获的。
匿名方法不能访问外部范围的 ref 或 out 参数。
在“匿名方法块”中不能访问任何不安全代码。
在 is 运算符的左侧不允许使用匿名方法。
示例
下面的示例演示实例化委托的两种方法:
• 使委托与命名方法 (DoWork) 关联。
• 使委托与匿名方法关联。
两种方法都会在调用委托时显示一条消息
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MvcUsedKeywords
{
//声明委托
delegate void Printer(string s);
delegate void Del();
class TestDelegate2
{
static void Main(string[] args)
{
//利用已命名的方法DoWork(),实例化一个委托
Printer p1 = new Printer(TestDelegate2.DoWork);
p1("我是中国人,我爱编程。(使用命名方法)");
//利用匿名方法,实例化一个委托
Printer p2=delegate(string s)
{
Console.WriteLine(s);
};
p2("我是中国人,我爱编程。(使用匿名方法)");
//利用该匿名方法的“外部”变量age
int age = 20;
Del p3 = delegate()
{
Console.WriteLine("年龄:{0}", age);
};
p3();
}
static void DoWork(string s)
{
Console.WriteLine(s);
}
}
}
运行结果:
我是中国人,我爱编程。(使用命名方法)
我是中国人,我爱编程。(使用匿名方法)
年龄:20