一.什么是委托
委托的本质是一种数据类型,和类类型一样,只是一种数据类型没什么神秘的地方,委托是一种引用数据类型,表示对具有特定参数列表和返回类型的方法的引用。在实例化委托时,你可以将其实例与任何兼容的方法(参数和返回值,简称方法的签名)相关联,再通俗一点的讲,委托是可以将"方法"定义成变量的数据类型。
二.为什么使用委托
委托用于将方法作为参数传递给其他方法,当某个方法直接调用有困难时,我们就想找一个"中间人"来帮我们调用,这个中间人就是委托。
委托的简单应用的第一个例子:从窗体向主窗体传递值,实现主窗体窗体刷新
主窗体:
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