標籤:style blog color 使用 os strong io 檔案
委託回調靜態方法和執行個體方法有何區別
- 當委託綁定靜態方法時,內部的對象成員變數_target會被設定成null
- 當委託綁定執行個體方法是,_target將會設定成指向該執行個體方法所屬的一個執行個體對象
- 當委託被執行時,該對象執行個體將會用來調用執行個體方法
1 class DelegateReturn 2 { 3 public delegate String GetStringDelegate(); 4 5 static string GetTypeName() 6 { 7 return typeof(DelegateReturn).ToString(); 8 } 9 static string GetTimeString()10 {11 return DateTime.Now.ToString();12 }13 static void TestDelegate() 14 {15 GetStringDelegate _myDelegate = new GetStringDelegate(GetTimeString);16 _myDelegate += GetTypeName;17 18 _myDelegate();19 //1隻有一個傳回值,GetTypeName傳回值20 foreach (Delegate d in _myDelegate.GetInvocationList())21 Console.WriteLine(d.DynamicInvoke());22 //2會有兩個傳回值23 }24 }
鏈式委託的執行順序是:按照委託鏈上的順序從當前委託開始一次往後執行,如果有需要,可以通過GetInvocationList()方法來獲得委託鏈上所有需要執行的委託,並且按照任何希望的順序去執行它們。
在上述第二種方法中,委託鏈中每個方法的傳回值都不會丟失
委託可以是帶有傳回值的方法,但多於一個帶傳回值的方法被添加到委託鏈中時,程式員需要受到地調用委託鏈上的每個方法,否則委託使用者將只能得到委託鏈上最後一個被執行方法的傳回值
1 /// <summary> 2 /// 自訂一個事件類型參數 3 /// </summary> 4 public class ConsoleEventArgs : EventArgs 5 { 6 private string _message; 7 public ConsoleEventArgs():base() 8 { 9 _message = String.Empty;10 }11 public ConsoleEventArgs(string message) :base() 12 {13 _message = message;14 }15 public string Message 16 {17 get 18 {19 return _message;20 }21 }22 }23 24 /// <summary>25 /// 管理主控台,在輸出前發出輸出事件26 /// </summary>27 public class ConsoleEventManager 28 {29 //定義控制台事件成員對象 30 public event EventHandler<ConsoleEventArgs> ConsoleEvent;31 /// <summary>32 /// 控制台輸出33 /// </summary>34 /// <param name="message">用來構造事件參數</param>35 public void ConsoleOutput(string message) 36 {37 ConsoleEventArgs args = new ConsoleEventArgs(message);38 }39 /// <summary>40 /// 負責發送事件41 /// </summary>42 /// <param name="args">事件參數</param>43 public virtual void SendConsoleEvent(ConsoleEventArgs args) 44 {45 //定義一個臨時的引用變數,這樣可以確保多線程訪問時不會發生問題46 EventHandler<ConsoleEventArgs> temp = ConsoleEvent;47 if(temp != null)48 {49 temp(this,args);50 }51 }52 }53 /// <summary>54 /// 日誌類型,訂閱控制台輸出事件55 /// </summary>56 public class Log 57 {58 private const String LogFile = "C:\\TestLog.txt";59 public Log(ConsoleEventManager cm) 60 {61 //訂閱控制台輸出事件62 cm.ConsoleEvent += WriteLog;63 }64 /// <summary>65 /// 事件處理方法,注意參數固定模式66 /// </summary>67 /// <param name="sender">事件寄件者</param>68 /// <param name="args">事件參數</param>69 private void WriteLog(object sender,EventArgs args) 70 {71 if(!File.Exists(LogFile))72 {73 using(FileStream fs = File.Create(LogFile)){}74 }75 FileInfo info = new FileInfo(LogFile);76 using(StreamWriter sw = info.AppendText())77 {78 sw.WriteLine(DateTime.Now.ToString()+"|"+sender.ToString()+"}"+((ConsoleEventArgs)args).Message);79 }80 }81 }
- 定義了事件使用的參數類型 ConsoleEventArgs
- 定義了事件類型的私人成員 ConsoleEventManager.ConsoleEvent
- 定義了事件發送的方法 ConsoleEventManager.SendConsoleEvent
- 訂閱事件 Log類型
當程式執行時,ConsoleEventManager類型負責在控制台輸出測試字串,同時,訂閱了控制台輸出事件的Log類型會在記錄檔中寫入同樣的內容
事件是一種使用對象或者類能夠通過提供通知的成員,用戶端可以通過提供事件處理為相應的事件添加可執行代碼,事件是一種特殊的委託
事件是一個委託類型,該委託類型的方法無傳回值,並且擁有兩個參數,object TEventArg
事件的訂閱和取消都是基於委託鏈表來實現的