委托(delegate)是一种可以把引用存储为函数的类型。
委托的声明类似于函数,但不带函数体,且要使用delegate关键字,委托的声明指定了一个返回类型和一个参数列表。
在定义了委托之后,就可以声明该委托的变量。接着把这个变量初始化未与委托有相同返回类型和参数列表的函数引用。之后,就可以使用委托变量调用这个函数,就想该变量是一个函数一样。
using System; namespace TestDelegate { class Program { delegate double ProcessDelegate(double param1, double param2); static double Multiply(double param1, double param2) { return param1 * param2; } static double Divide(double param1, double param2) { return param1 / param2; } static void Main(string[] args) { ProcessDelegate process; double input1 = 10.0; double input2 = 2.0; string input = Console.ReadLine(); if (input == "*") { process = new ProcessDelegate(Multiply); } else { process = new ProcessDelegate(Divide); } Console.WriteLine("Result:{0}",process(input1,input2)); Console.ReadKey(); } } }
当实例化委托时,参数是函数名,而当使用的时候,把委托实例名称作为函数名使用了,而此时规律是,委托类型和函数的返回值和参数列表一致。
如果把函数的参数列表改一个,就出现编译时错误。
错误 1 “Multiply”的重载均与委托“TestDelegate.Program.ProcessDelegate”不匹配
使用委托的四部曲:
- 定义一种委托类型
- 委托执行时要调用方法
- 定义一个委托实例
- 委托实例的调用
我知道在.Net中事件都是通过委托来实现的,那我找个例子。.NET中经常使用的控件Button,当我们把Button 控件 drap and drop到界面,然后双击界面的Button我们发现程序中自动生成了一个响应Button的事件方法,然后我们给事件方法添加Code之后,当我们点击该Button就响应该方法了,但我们没有看到代码中有任何的委托和事件之类的定义,其实这些.NET都已经做好了。我们可以查看如下文件。
图2事件委托实现
其中,EventHandler就是一个代理类型,可以认为它是一个“类”,是所有返回类型为void,具备两个参数分别是object sender和EventArgs e,第一个参数表示引发事件的控件,或者说它表示点击的那个按钮。通过以下的代码我们细细解析一下。
private void button1_Click(object sender, EventArgs e) { //获取被点击Button的实例 Button objBotton = sender as Button; if (objBotton != null) { objBotton.Text = "Hello you click me."; objBotton.AutoSize = true; } else { //Exception Handle. } }