##委託html
簡單記錄點東西 適合似懂非懂的朋友看看 委託類型用來定義和響應應用程序中的回調。 藉此能夠設計各類有面向對象特性的代碼模式。下面要說的事件在我看來就是委託的一種實現,再深一步講,利用委託加事件,是否是能夠構建各類所謂的管道框架。 如
ASP.NET WebAPI
的管道模型,整個消息處理管道是經過一組有序的HttpMessagHandler
「首尾相連」而成,具體實現「串聯」的是經過DelegatingHandler
這個類型來完成的。便是一組委託鏈
。框架
最精華的內容您已看完函數
委託定義 public delegate int DeleName(int x); 名稱 參數 返回值spa
##一、委託簡單示例設計
DeleName del = M1; public int M1(int i) { ... }
入門理解1:委託是方法的類型,即委託=class,方法=new class()code
上面的方法名稱M1只起到傳遞做用時,能夠用匿名委託代替:htm
DeleName del = delegate (int i) { ... };
除了用匿名委託,還能夠用lamda表達式進行代替:對象
DeleName del = (int i)=> { ... };
###在這裏也能看出lamda本質就是委託blog
##二、泛型委託事件
public delegate void MyGenericDelegate1<T>(T arg); public delegate int MyGenericDelegate2<T,M>(T arg,M name); MyGenericDelegate1<int> intTarget = new MyGenericDelegate<int>(IntTarget); static void IntTarget(int arg) => Console.WriteLine($"IntTarget--> {++arg}"); MyGenericDelegate2<int,string> intTarget1 = (int arg,string name) => { return 1; };
好處:封裝爲了複用
看下上面兩個委託的命名:MyGenericDelegate1 MyGenericDelegate2 純粹爲了取名而取名,此時咱們能夠不本身取名。 怎麼作呢,C#自己提供了兩個泛型委託能夠給咱們使用,且可知足大多數場景。
##三、泛型Action<> 和 Func<> 委託
(可指向至多傳遞16個參數的方法)
Action<>:無返回值: 定義 public delegate void Action<...>
public static void Show() { // 使用Action<>委託來指向 DisplayMessage() Action<string, ConsoleColor, int> actionTarget = new Action<string, ConsoleColor, int>(DisplayMessage); actionTarget("actionTarget", ConsoleColor.Red, 5); } // Action<> 委託的一個目標 private static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount) { ... }
Func<>:有返回值 public delegate TResult Func<..., out TResult> TResult:返回值類型
Func<int, int, int> funcTarget = new Func<int, int, int>(Add); funcTarget(1, 2); static int Add(int x, int y) => x + y;
若是你以爲一個具備自定義名稱的委託更有助於捕獲問題範疇,那麼構建自定義委託不過就是一行代碼的事兒。
注:Linq中就大量的用到了 Action<> 和 Func<>。
##四、事件
最簡單的說法是:能夠把事件當作是委託的一個實例。委託比做類:它定義了函數的簽名(接受什麼類型的參數 返回什麼類型的值)事件比做委託new出來的一個實例,是具備該委託簽名的具體函數。固然事件和實例也是有區別的: 一、事件這個東西 能容納不少個具體的函數(經過+= -= 增長刪除)。 二、事件有event關鍵字起到了保護做用不容許改變事件的引用。即在聲明事件的類外部不能用=對事件對象賦值
###直接看看代碼
public delegate void HelloWorldDelegate(string name); public class HelloWorldClass2 { public event HelloWorldDelegate del;//!!!!event修飾了委託對象 public void HelloWorld(string name) { //del = (n) => { Console.WriteLine(n); };//在聲明事件的類內部能夠用=直接定義事件的引用(賦值) del(name); } } class Program { static void Main(string[] args) { HelloWorldClass2 h2 = new HelloWorldClass2(); //h2.del = ByEnglish;//不容許改變事件的引用(不能用=賦值) h2.del += ByEnglish;//第一種 //手工建立一個委託變量是最直接的方式。可是大多數狀況下,咱們並不依靠委託對象。咱們可使用C#提供的方法組轉換的方法,它容許咱們在調用以委託做爲參數的方法時直接提供了與委託指望的簽名想匹配的方法的名稱(返回 void,參數 string),而不是建立委託對象。(因此通常直接用上面這種) HelloWorldDelegate de = ByChinese; h2.del += de;//第二種 h2.HelloWorld("mary"); Console.ReadLine(); } static void ByEnglish(string name) { Console.WriteLine("hello,world"+name); } static void ByChinese(string name) { Console.WriteLine("你好,世界" + name); } }
事件默認是個多播委託,什麼是多播委託呢?就是上面的h2.del委託容納的方法有多個,ByEnglish跟ByChinese,用+=能夠繼續往下延伸。
委託和事件的區別在於,事件是個規約,委託是個實現(固然抽象上的委託也能夠不是個具體的實現)。 規約的含義是,我定義了這麼個語法,你能夠經過+=和-=把委託掛載到這個東西(事件)上,當發生這個事件的時候,我會確保這些委託都被獲得調用。可是具體是怎麼調用的,你不用關心。
歡迎討論~ 感謝閱讀~
我的公衆號: