一.什么是委托
委托的本质是一种数据类型,和类类型一样,只是一种数据类型没什么神秘的地方,委托是一种引用数据类型,表示对具有特定参数列表和返回类型的方法的引用。在实例化委托时,你可以将其实例与任何兼容的方法(参数和返回值,简称方法的签名)相关联,再通俗一点的讲,委托是可以将"方法"定义成变量的数据类型。
二.为什么使用委托
委托用于将方法作为参数传递给其他方法,当某个方法直接调用有困难时,我们就想找一个"中间人"来帮我们调用,这个中间人就是委托。
委托的简单应用的第一个例子:从窗体向主窗体传递值,实现主窗体窗体刷新
主窗体:
public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); FrmOther objFrm = new FrmOther(); //将从窗体的委托变量和主窗体的对应方法关联 objFrm.msgSender = this.Receiver; objFrm.Show(); } /// <summary> /// 接收委托传递的信息 /// </summary> /// <param name="counter"></param> private void Receiver(string counter) { this.lblCount.Text = counter; } } //【1】声明委托 public delegate void ShowCounter(string counter);
从窗体:
public partial class FrmOther : Form { public FrmOther() { InitializeComponent(); } //根据委托创建委托对象 public ShowCounter msgSender; //计数 private int counter = 0; private void btnClick_Click(object sender, EventArgs e) { counter++; if (msgSender != null) { msgSender(counter.ToString()); } } }
委托的简单应用第二个例子 主窗体向从窗体广播:
主窗体代码:
public FrmMain() { InitializeComponent(); FrmOther01 objFrm01 = new FrmOther01(); FrmOther02 objFrm02 = new FrmOther02(); FrmOther03 objFrm03 = new FrmOther03(); //将委托变量和具体方法关联 this.msgSender += objFrm01.Receiver; this.msgSender += objFrm02.Receiver; this.msgSender += objFrm03.Receiver; objFrm01.Show(); objFrm02.Show(); objFrm03.Show(); } //根据委托创建委托对象 public ShowCounter msgSender; private int counter = 0; private void btnClick_Click(object sender, EventArgs e) { counter++; //同时对三个从窗体发消息 this.msgSender.Invoke(counter.ToString()); } private void btnReset_Click(object sender, EventArgs e) { counter = 0; this.msgSender("0"); } } //【1】声明委托 public delegate void ShowCounter(string counter);
从窗体代码:
public partial class FrmOther01 : Form { public FrmOther01() { InitializeComponent(); } /// <summary> /// 接收委托传递的信息 /// </summary> /// <param name="counter"></param> public void Receiver(string counter) { this.lblCount.Text = counter; } }
三.动态创建委托
委托是C#实现事件的基础,有时候不可避免的要动态创建委托,实际上委托也是一种类型:System.Delegate,所有的委托都是从这个类派生而来,System.Delegate提供了一些方法可以动态创建委托:
A.创建静态方法的委托
CreateDelegate(Type, MethodInfo) 和 CreateDelegate(Type, MethodInfo, Boolean) 的功能是相同的,都是可以创建静态方法的委托,或者是显式提供实例方法的第一个隐藏参数(称开放的实例方法,从 .Net Framework 2.0 以后支持)的委托。举个例子:
public partial class Form1 : Form { public delegate void D1(string s); Type objType = Type.GetType("WindowsFormsApplication4.TestClass"); D1 d1; public Form1() { InitializeComponent(); Delegate objDelegate = CreateStaticDelegate(); d1 = (D1)objDelegate; d1("11111111"); } Delegate CreateStaticDelegate() { Delegate objDelegate = Delegate.CreateDelegate(typeof(D1), objType.GetMethod("TestStaticMethod")); return objDelegate; } } public class TestClass { public static void TestStaticMethod(string str) { } public void TestMethod() { } }
创建静态方法TestStaticMethod的委托 需要typeof(Action<string>) ,已及需要用反射获取需要被触发的方法。
B.创建实例方法委托
要创建实例方法 TestMethod 方法的委托,例子如下:
1 public partial class Form1 : Form 2 { 3 public delegate void D1(string s); 4 Type objType = Type.GetType("WindowsFormsApplication4.TestClass"); 5 //TestClass objTestClass = new TestClass(); 6 D1 d1; 7 8 public Form1() 9 { 10 InitializeComponent(); 11 Delegate objDelegate = CreateDelegate(); 12 d1 = (D1)objDelegate; 13 d1("11111111"); 14 } 15 Delegate CreateDelegate() 16 { 17 18 object objTestClass = Activator.CreateInstance(objType); 19 20 21 Delegate objDelegate = Delegate.CreateDelegate(typeof(D1), objTestClass, "TestMethod"); 22 return objDelegate; 23 } 24 } 25 26 public class TestClass 27 { 28 public static void TestStaticMethod(string str) { } 29 public void TestMethod(string str) 30 { 31 Console.WriteLine(str); 32 33 Console.Read(); 34 35 } 36 }
关于Delegate其它的重载方法可以参照MSDN,链接如下:
https://docs.microsoft.com/en-us/dotnet/api/system.delegate.createdelegate?view=netframework-4.5
来源:https://www.cnblogs.com/Artist007/p/11043395.html