一.什麼是委託api
委託的本質是一種數據類型,和類類型同樣,只是一種數據類型沒什麼神祕的地方,委託是一種引用數據類型,表示對具備特定參數列表和返回類型的方法的引用。在實例化委託時,你能夠將其實例與任何兼容的方法(參數和返回值,簡稱方法的簽名)相關聯,再通俗一點的講,委託是能夠將"方法"定義成變量的數據類型。this
二.爲何使用委託spa
委託用於將方法做爲參數傳遞給其餘方法,當某個方法直接調用有困難時,咱們就想找一個"中間人"來幫咱們調用,這個中間人就是委託。3d
委託的簡單應用的第一個例子:從窗體向主窗體傳遞值,實現主窗體窗體刷新code
主窗體:orm
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()); } } }
委託的簡單應用第二個例子 主窗體向從窗體廣播:blog
主窗體代碼:事件
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);
從窗體代碼:get
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