一、Delegate委託可以理解為一個方法簽名。
可以將方法作為另外一個方法的參數帶入其中進行運算。在C#中我們有三種方式去建立委託,分別如下:
public delegate void Print(string str); static void delegatemethod(string str) { Console.WriteLine(str); } public static void Main() { #region 委託 //1.普通委託 var print1 = new Print(delegatemethod); print1("這是普通方式建立的委託"); //2.匿名委託 Print print2 = delegate(string str) { Console.WriteLine(str); }; print2("這是匿名方式建立的委託"); //3.lambda委託 Print print3 = (string str) => { Console.WriteLine(str); };
}
二、Event事件,是一種封裝過的委託。
它擁有以下三要素:
1.事件發行者-達到某些條件時激發事件的對象
2.事件訂閱者-訂閱事件並對事件發生時進行處理的對象
3.定義發行者和訂閱者關係,一個發行者可能會有多個訂閱者。
三、事件和委託的區別
1.委託允許直接通過委託去訪問相應的處理函數,而事件只能通過公布的回呼函數去調用
2.事件只能通過“+=”,“-=”方式註冊和取消訂戶處理函數,而委託除此之外還可以使用“=”直接賦值處理函數。
最後我們可以看看整個自訂事件的處理辦法以及事件和委託的區別如下代碼:
//事件參數 public class My_EventArgs : EventArgs { private string _args = string.Empty; public My_EventArgs(string args) { _args = args; } public string Args { get { return _args; } } } //事件發行者 public class SourceClass { public double Width { get; set; } public double Height { get; set; } My_EventArgs Evargs; public SourceClass(string args) { Evargs = new My_EventArgs(args); } //定義委託 public delegate void EventHandler(object sender, My_EventArgs args); #region 使用委託方式聲明 public EventHandler Clicked; public void ClickedAsync() { if (Clicked != null) { Clicked(this, Evargs); } } #endregion #region 使用事件方式聲明 public event EventHandler Click; public void ClickAsync() { if (Click != null) { Click(this, Evargs); } } #endregion } //事件訂閱者 public class Del { public delegate void Print(string str); static void delegatemethod(string str) { Console.WriteLine(str); } public static void Main() { #region 委託 //1.普通委託 var print1 = new Print(delegatemethod); print1("這是普通方式建立的委託"); //2.匿名方法
Print print2 = delegate(string str) { Console.WriteLine(str); }; print2("這是匿名方法建立的委託"); //3.lambda委託 Print print3 = (string str) => { Console.WriteLine(str); }; print3("這是lambda方式建立的委託"); #endregion #region 事件 SourceClass source = new SourceClass("我的事件被觸發"); source.Width = 5.0; source.Height = 3.0; //一、委託方式允許source.Clicked(source, new My_EventArgs("我使用委託方式調用的Args"));調用 source.Clicked = new SourceClass.EventHandler(source_RightClick); source.Clicked += new SourceClass.EventHandler(source_LeftClick); source.ClickedAsync(); source.Clicked(source, new My_EventArgs("我使用委託方式調用的Args")); //二、很明顯使用者希望通過使用source.ClickedAsync();去調用函數,而非直接使用上行代碼去調用,所以在這裡需要使用Event關鍵字進行申明 //注1.事件方式不允許source.Clicked(source, new My_EventArgs("我使用委託方式調用的Args"));直接調用 //注2.事件不允許 source.Click = new SourceClass.EventHandler(source_LeftClick);直接賦值 source.Click += new SourceClass.EventHandler(source_LeftClick); source.ClickAsync(); //登出事件和註冊事件 source.Click -= new SourceClass.EventHandler(source_LeftClick); source.Click += new SourceClass.EventHandler(source_RightClick); source.ClickAsync(); Console.ReadLine(); #endregion } //事件處理方法1 static void source_LeftClick(object sender, My_EventArgs args) { SourceClass source = sender as SourceClass; Console.WriteLine("目標寬度:" + source.Width + ",目標高度:" + source.Height); Console.WriteLine("目標對象參數:"+args.Args); } //事件處理方法2 static void source_RightClick(object sender, My_EventArgs args) { SourceClass source = sender as SourceClass; Console.WriteLine("目標面積:" + source.Width *source.Height); } }
啟動並執行如下: