一、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); } }
運行的效果圖如下: