在C#編程中方法的回調有以下幾種方式
通過接口、通過委托、定時回調、多線程回調,異步回調
下面就以代碼的形式來講解這種方式
通過接口回調
代碼示例如下
定義接口,定義了一個Run 方法:
interface ICallBack { void Run(); }
定義實現接口的類,並實現接口中定義的方法,方法的作用就是輸出當前時間:
class CallBackClass:ICallBack { public void Run() { Console.WriteLine(DateTime.Now); } }
定義“控制回調器“類,定義一個接口類型的字段,用於引用回調對象。定義一個ByInterface方法,用於執行回調:
class Controller { //接口回調 private readonly ICallBack _callBackObject = null; public Controller(ICallBack obj) { this._callBackObject = obj; } public void ByInterface() { Console.WriteLine("敲擊任意鍵顯示當前時間,ESC鍵退出..."); while (Console.ReadKey(true).Key != ConsoleKey.Escape) { this._callBackObject.Run(); } } }
在Main方法中執行:
static int Main(string[] args) { Controller controller = new Controller(new CallBackClass()); controller.ByInterface(); return 0; }
執行結果:
| 敲擊任意鍵顯示當前時間,ESC鍵退出... 2015/08/10 16:03:22 |
大家對於在Controller類中ICallBack接口變量的使用有什么看法?
我覺得在控制回調器中用接口類型做字段,無疑會降低類與類之間的耦合度,不局限於某一特定的類,只要是實現了接口的對象都可以被調用,這樣的程序設計才是被提倡的。
通過委托實現回調
關於委托有這樣一句話:.NET 來通過委托提供了一種回調函數機制
所以說使用委托實現回調是最直截了當的的方式了,下面是代碼示例。
控制回調器類代碼
class Controller { //定義一個委托類型的字段 private Action showTime = null;
//構造函數內接收外界提供的方法 public Controller(Action showTime) { this.showTime += showTime; } public void ByDelegate() { Console.WriteLine("敲擊任意鍵顯示當前時間,ESC鍵退出..."); while (Console.ReadKey(true).Key != ConsoleKey.Escape) { this.showTime(); } } }
在Main方法中執行:
static int Main(string[] args) { Controller controller = new Controller(new Action(()=>Console.WriteLine(DateTime.Now))); controller.ByDelegate(); }
執行結果和通過接口回調的示例一樣,在此就不展示結果了
上述代碼中的紅字為lambda表達式寫的匿名方法;
由於委托允許動態的添加(+=)和移除(-=)回調方法,所以比接口使用起來更加靈活
通過定時回調
這種方式應用場景比較特殊,需要以固定的時間間隔調用某個方法。
利用了.NET Framework提供的Timer類,定時回調一個滿足TimerCallBack委托要求的方法,此委托定義如下:
public delegate void TimerCallback(object state);
該委托定義了一個object類型參數的方法 Timer類構造函數如下:
public Timer(TimerCallback callback, object state, int dueTime, int period)
參數解析:
callback:定時回調的方法
state:向回調方法傳遞的參數
dueTime:開發執行回調方法之前延遲的時間,單位是秒。設為0為立即調用回調方法
period:執行回調方法的間隔秒數
示例如下:
public class TaskInfo { public int Count = 0; } static class Program { static void Main() { var ti=new TaskInfo(); var tm = new Timer( obj => { var taskInfo = obj as TaskInfo; taskInfo.Count++; Console.WriteLine(taskInfo.Count); } , ti, 0, 1000); Console.ReadKey(); tm.Dispose(); } }
上述代碼中紅字為匿名函數,使用了lambda表達式。
關於多線程回調和異步回調下篇再續~謝謝
