1、是什麼編程
1)委託包含對方法而不是方法名稱的引用。使用委託能夠在運行時動態設定要調用的方法,不知道方法名稱,也能夠調用方法,執行(或調用)一個委託將執行該委託引用的方法。ide
2)委託將名稱與方法的定義鏈接起來,即將方法的實現附加到該名稱。這樣即可以使用該名稱調用特定的方法。可是,委託要求方法的實現和委託必須具備相同的方法簽名(也就是說,他們應該具備相同數量/類型的參數),並有相同類型的返回值。函數
3)委託更像一個具備通用的方法名稱,在不一樣的狀況將該名稱指向不一樣的方法,並經過委託執行這些方法。this
2、怎麼用spa
使用委託包括三個步驟:.net
1)定義委託線程
2)實例化委託指針
3)使用委託code
咱們上一個例子:orm
class Program { //定義一個委託 public delegate int Call(int num1, int num2); class Math { public int Mutiply(int num1, int num2) { return num1 * num2; } public int Divide(int num1, int num2) { return num1 / num2; } } static void Main(string[] args) { Call objCall; Math objMath = new Math(); objCall = new Call(objMath.Mutiply);//實例化一個委託 int result = objCall(5, 3);//使用委託 Console.WriteLine("結果爲 {0}", result); } }
值得說明是,
objCall = new Call(objMath.Mutiply);//實例化一個委託
objCall = objMath.Mutiply; //直接給委託賦值
這兩種方式效果是同樣的,只是兩種不一樣的寫法。用.net reflector反編譯上述代碼,會發現其實objCall = objMath.Mutiply最終仍是會編譯生成objCall = new Call(objMath.Mutiply)。
上面的例子,咱們再進一步,用匿名委託實現:
static void Main(string[] args) { Call objCall = delegate(int num1, int num2) { return num1 * num2; };//匿名委託 int result = objCall.Invoke(3, 5);//使用委託 Console.WriteLine("結果爲 {0}", result);//輸出:結果爲 15 }
咱們還能夠將:
int result = objCall.Invoke(3, 5);//使用委託
替換爲:
int result = objCall(3, 5);//使用委託
效果是同樣的。
再進一步,用Lambda表達式進行簡化,能夠將:
Call objCall = delegate(int num1, int num2) { return num1 * num2; };//匿名委託
替換爲:
Call objCall = (int num1, int num2) => { return num1 * num2; };//Lambda表達式
更簡化一步,變爲:
Call objCall = (num1, num2) => { return num1 * num2; };//Lambda表達式
這就是C#委託的進化過程以及C#Lambda表達式對委託的支持。
3、何時用
1)委託相似於C語言中的函數指針,能夠將方法做爲函數的參數進行傳遞
2)當不知道方法的具體實現時,就能夠定義個委託,讓它替咱們幹活
3)咱們在編程時用的最多的就是事件註冊時使用。
好比:
this.button1.Click += new EventHandler(button1_Click);//button1註冊Click事件
private void button1_Click(object sender, EventArgs e) { //方法具體實現內容 }
能夠看到方法button1_Click做爲參數傳遞給了EventHandler委託。
再好比在線程方法中:
Thread th = new Thread(new ThreadStart(Method));//這裏的ThreadStart就是一個委託,裏面能夠直接傳一個方法名Method,以委託的形式調用方法 th.IsBackground = true; th.Start();
4、典型應用
好比兩個窗體Form1(一個文本框,一個按鈕)、Form2(一個文本框,一個按鈕)之間進行傳值,Form1到Form2能夠經過構造函數傳值,但若是要將Form2的值傳回給Form1該怎麼辦呢?這裏就能夠用到委託,這也是委託的經典應用場景之一。
Form1.cs部分代碼:
private void button1_Click(object sender, EventArgs e) { Form2 form2 = new Form2(); //經過public變量傳值 form2.text = this.textBox1.Text; //經過委託將子窗體的值傳回主窗體 form2.delegateShow = form2_ShowDelegateEventHandler; //經過註冊事件將子窗體的值傳回主窗體 form2.ShowDelegateEventHandler += new Form2.ShowDelegate(form2_ShowDelegateEventHandler); form2.Show(); } void form2_ShowDelegateEventHandler(string text) { this.textBox1.Text = text; }
Form2.cs部分代碼:
public delegate void ShowDelegate(string text);//聲明委託 public event ShowDelegate ShowDelegateEventHandler;//聲明事件 public string text;//public變量 public ShowDelegate delegateShow;//public委託變量 private void Form2_Load(object sender, EventArgs e) { this.textBox1.Text = text; } private void button1_Click(object sender, EventArgs e) { //寫法1:用事件 if (ShowDelegateEventHandler != null) ShowDelegateEventHandler(this.textBox1.Text); //寫法2:用委託 delegateShow(this.textBox1.Text); this.Close(); }
5、總結
1)委託是方法的簽名,能夠將委託做爲方法的參數進行傳遞
2)事件基於委託,或者說事件是特殊的委託
3)委託能夠用匿名委託簡化代碼(不須要再聲明委託,而後實現),還能夠用Lambda表達式進一步簡化匿名委託(這也是C#推薦的方式)。
代碼下載:https://files.cnblogs.com/files/guwei4037/委託和事件窗體傳值.zip