饮水思源:金老师的自学网站
委托(Delegate)
“不学会委托(Delegate),等于没学.NET编程!”
例程1-委托类型变量
using System; namespace ConsoleApp1 { class Program { // 1. 定义一个委托类型 public delegate int MathOptDelegate(int value1, int value2); public static int add(int a, int b) { return a + b; } static void Main(string[] args) { // 2. 委托类型变量可以接收一个方法引用(实例方法、静态方法都可以) MathOptDelegate mathOpt = Program.add; Console.WriteLine(mathOpt(1, 2)); // => 3 Console.ReadKey(); } } }
/
例程2-以委托变量作为参数的方法
using System; namespace ConsoleApp1 { class Program { // 1. 定义一个委托类型 public delegate void doSomething(); // 2. 定义一个以委托类型变量作为参数的方法 public static void sampleMethod(doSomething doSomething) { Console.WriteLine("begin to do something."); doSomething(); Console.WriteLine("stop doing something."); } // 3. 定义一个与委托类型匹配的方法 public static void sayHello() { Console.WriteLine("hello"); } static void Main(string[] args) { sampleMethod(sayHello); Console.ReadKey(); // => begin to do something. // => hello // => stop doing something. } } }
/
例程3-委托调用列表(多路委托)
using System; namespace ConsoleApp1 { class Program { // 1. 定义一个委托类型 public delegate void doSomething(); // 2. 定义2个与委托类型匹配的方法 static void SayHello() => Console.WriteLine("hello"); static void SayGoodbye() => Console.WriteLine("Goodbye"); static void Main(string[] args) { doSomething doSomething = SayHello; doSomething += SayGoodbye; doSomething(); // => hello // => Goodbye Console.WriteLine(doSomething.GetInvocationList().Length); // => 2 doSomething -= SayHello; doSomething -= SayHello; doSomething -= SayHello; doSomething(); // => Goodbye Console.ReadKey(); // PS. 若有返回值,则委托变量的返回值是最后调用方法的返回值 } } }
Click事件探究
.NET的事件响应机制也是用委托来实现的,以实现Click事件为例,大概分为如下几个步骤↓
1、定义一个委托类型(该类型被定义在System命名空间中)
public delegate void EventHandler(object sender, EventArgs e);
2、声明一个委托类型变量(该变量被定义在相应组件中)
public event EventHandler Click;
加event和不加event的区别在于,加了event,事件只能由事件源对象激发,外界无法通过访问该变量激发。
3、挂载事件
this.button2.Click += new System.EventHandler(this.button2_Click);
button2_Click满足EventHandler的规范,该方法在适当的时候会被调用:
private void button2_Click(object sender, EventArgs e) { }
/
例程-动态挂载响应方法
using System; using System.Windows.Forms; namespace WindowsFormsApp1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void resp1(object sender, EventArgs e) { MessageBox.Show("响应1"); } private void resp2(object sender, EventArgs e) { MessageBox.Show("响应2"); } private void button1_Click(object sender, EventArgs e) { button3.Click -= resp2; button3.Click -= resp1; // 防止累加 button3.Click += resp1; // 上面为简单写法, // 等价写法:button3.Click += new EventHandler(resp1); } private void button2_Click(object sender, EventArgs e) { button3.Click -= resp1; button3.Click -= resp2; // 防止累加 button3.Click += resp2; } } }