<ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>


      1、為什么要用委托

      我們?yōu)槭裁匆形??任何東西存在即合理,不合理的也會被時(shí)間淘汰掉,委托既然存在肯定有存在的必要,我們來看一下什么時(shí)候可以用到委托。

      接下來我們有個(gè)需求,就是調(diào)用一個(gè)方法,取出1-1000個(gè)數(shù)字中所有是10的倍數(shù)的數(shù)字
      public static List<int> GetNum() { List<int> lst = new List<int>(); //
      這個(gè)算法是最簡陋的,但是舉這個(gè)例子是最合適的 for (int i = 1; i < 1000; i++) { if (i%10==0) {
      lst.Add(i); } }return lst; }

      這個(gè)很好寫,但是如果有一天,我們的需求變了,想取出1-1000個(gè)數(shù)字中所有是8的倍數(shù)的數(shù)字,那我們應(yīng)該怎么寫?是不是只要將if里面的條件改為i%8==0就行了,但是有一點(diǎn)變動的話就修改方法,說明這個(gè)方法寫的并不好,如果方法很復(fù)雜的話修改也很艱難。可能有人會說在添加一個(gè)獲取是8的倍數(shù)的方法,這樣的話會增加數(shù)據(jù)冗余,也就是重復(fù)的內(nèi)容。

      如果我們可以傳遞方法的話,只要傳過來一個(gè)(有一個(gè)參數(shù)為int類型返回值為Boolean類型的方法),這個(gè)問題將不是問題
      public static List<int> GetNum(有一個(gè)int類型的參數(shù)返回值為Boolean類型的方法) { List<int> lst =
      new List<int>(); for (int i = 1; i < 1000; i++) { if
      (有一個(gè)int類型的參數(shù)返回值為Boolean類型的方法) { lst.Add(i); } }return lst; }
      是不是我們將想要獲取什么樣的數(shù)字
      這個(gè)操作來交給了調(diào)用者,無論調(diào)用者想獲取1-1000以內(nèi)什么樣的數(shù)字都可以完成。但是這個(gè)方法的前提就是可以傳遞方法,這個(gè)時(shí)候我們就需要用到委托了。

      2、委托如何使用

      委托其實(shí)就是一個(gè)能夠指向方法的 指針,定義了一個(gè)委托就是定義了一個(gè) 類型

      首先我們先來定義一個(gè)委托,也就是定義一個(gè)類型
      //訪問修飾符 委托關(guān)鍵字 方法的返回值類型 要定義的類型名(參數(shù)1,參數(shù)2.....); public delegate Boolean
      DelegateFunc(int x);
      委托定義好了,也就是說我們已經(jīng)定義好了一個(gè)DelegateFunc類型,這個(gè)類型的使用方法就和public class DelegateFunc{}
      寫了一個(gè)類是一樣的,因?yàn)槎际嵌x了一個(gè)類型,既然大家都是類型,那用法肯定都是一樣的,我們先來看一下聲明普通的類型是如何聲明的
      //類型 變量名 = 實(shí)例化一個(gè)Object類型的對象(構(gòu)造函數(shù)有無參數(shù)) Object obj = new Object();
      而DelegateFunc既然也是我們定義好的一個(gè)類型,那用法自然一樣(因?yàn)闃?gòu)造函數(shù)需要參數(shù),所以下面這樣寫是不對的,沒有傳入?yún)?shù))
      //類型 變量名 = 實(shí)例化一個(gè)DelegateFunc類型的對象(構(gòu)造函數(shù)有無參數(shù)) DelegateFunc func = new
      DelegateFunc();
      委托是一個(gè)能夠指向方法的指針,而它的構(gòu)造函數(shù)就是需要一個(gè)方法,接著我們來定義一個(gè)返回值為Boolean,能接收一個(gè)int類型參數(shù)的方法
      //相當(dāng)于方案1 public static Boolean Condition1(int i) { //模擬復(fù)雜的操作 相當(dāng)于return i%10==0;
      int x = i % 10; if (i % 10 == 0) { return true; } else { return false; } }
      定義好了方法我們再來實(shí)例化一個(gè)DelegateFunc類型的對象
      //構(gòu)造函數(shù)放入方法的話不需要帶(),帶()的話是調(diào)用 DelegateFunc func = new DelegateFunc(Condition1);
      下面看一下下面這種聲明委托類型的方式
      //同樣都是類型Object類型可以這樣寫 //因?yàn)镾tring最終是繼承自O(shè)bject,并且String可以默認(rèn)轉(zhuǎn)換為Object Object obj =
      "obj"; //而DelegateFunc也可以通過這種方式賦值,這說明Condition1可以默認(rèn)轉(zhuǎn)換為委托類型 DelegateFunc func =
      Condition1;
      實(shí)例化完成之后func變量就會指向Condition1方法,調(diào)用方式如下
      //調(diào)用委托類型的對象和調(diào)用普通的方法是一樣的 func(10);
      然后我們把剛才寫的GetNum方法修改為如下的樣子,參數(shù)為接收一個(gè)DelegateFunc類型的參數(shù),也就是委托類型
      public static List<int> GetNum(DelegateFunc func) { List<int> lst = new List<
      int>(); for (int i = 1; i < 1000; i++) { //調(diào)用傳過來的方法,根據(jù)調(diào)用者傳過來的方法拿到想要的數(shù)字 if
      (func(i)) { lst.Add(i); } }return lst; }
      在Main方法中調(diào)用GetNum方法
      //聲明委托 DelegateFunc func = new DelegateFunc(Condition1); //調(diào)用方法 List<int> lst =
      GetNum(func);//也可以直接調(diào)用,因?yàn)槎紩J(rèn)轉(zhuǎn)換 //List<int> lst = GetNum(Condition1); //輸出
      foreach (int item in lst) { Console.WriteLine(item); }
      ?

      輸出



      如果我們有新的方案的話,只需要在新建一個(gè)方案,然后傳入方法中,比如我們還看剛才那個(gè)求1-1000以內(nèi)8的倍數(shù),我們只需要聲明一個(gè)新的方案
      //聲明一個(gè)新的方案2 public static Boolean Condition2(int i) { //同樣模擬復(fù)雜的操作 相當(dāng)于return
      i%8==0; int x = i % 8; if (i % 8 == 0) { return true; } else { return false; } }
      然后和剛才一樣,聲明一個(gè)委托就行,傳入GetNum就行。

      不過我們看一下,雖然已經(jīng)比較簡化代碼了,但是寫起來還是很麻煩,然后我們來看一下lambda表達(dá)式

      3、lambda表達(dá)式


      首先lambda表達(dá)式只是方法的一種寫法!lambda聲明的方法是匿名方法,它和委托并不是綁死的,這是兩個(gè)東西,但是lambda表達(dá)式和委托結(jié)合使用是非常常見的!

      ?看一下lambda表達(dá)式的語法,也就是函數(shù)的另一種寫法
      //可以這樣寫 //DelegateFunc func = new DelegateFunc((i) => //{ // return i % 8 == 0;
      //}); //也可以這樣 不進(jìn)行new DelegateFunc操作,因?yàn)闀J(rèn)轉(zhuǎn)換 //如果有多句的話,這樣寫每一句通過分號隔開 DelegateFunc
      func = (i) => {return i % 8 == 0; }; //如果只有單句 不用寫return 默認(rèn)reuturn i%8==0
      這一句計(jì)算出來的值 func = (i) => i % 8 == 0; //如果只有一個(gè)參數(shù) 多個(gè)參數(shù)的話要(i,j,....)這樣寫 func = i =>
      i %8 == 0;
      除此之外lambda也可以用來聲明方法,貌似只能寫一句,,,,
      //無返回值 public static void HelloWord() => Console.WriteLine("Hello Word!"); //
      有返回值 public static String GetHelloWord() => "Hello Word!";
      有了lambd我們再來調(diào)用GetNum,就會變得非常方便
      //8的倍數(shù) List<int> lst = GetNum((i) => i % 8 == 0); //10的倍數(shù) lst = GetNum(i => i %
      10 == 0); //20的倍數(shù) lst = GetNum(i => i % 20 == 0);
      4、Action和Func

      Action和Func是微軟已經(jīng)定義好的的兩種委托類型,區(qū)別是Action是沒有返回值的,而Func是需要返回值的

      Action使用方法
      //無參數(shù) Action action1 = () => Console.WriteLine("action"); //有參數(shù)的話調(diào)用Action<T>
      Action<int> action2 = (i) => Console.WriteLine(i); //多個(gè)參數(shù)就在生命的時(shí)候<T,T,T> Action<
      int,string> action3 = (i, str) => Console.WriteLine(i+"\t"+str); //調(diào)用
      action1(); action2(10); action3(10,"s");
      運(yùn)行結(jié)果:



      Func使用方法
      //Func是沒有Func類型的,只有Func<T>類型 Func<string> func1 = () => "func"; //如果需要參數(shù)
      Func<T,T,T>//最后一個(gè)T類型為返回值類型,前面的全都為參數(shù)的類型!!! Func<string, int> func2 = (i) => int
      .Parse(i);//如果有多個(gè)參數(shù) 最后一個(gè)T類型為返回值類型,前面的全都為參數(shù)的類型!!! Func<int, string, int> func3 =
      (i, str) =>int.Parse(i + str); //調(diào)用 Console.WriteLine(func1());
      Console.WriteLine(func2("123")); Console.WriteLine(func3(1,"23"));
      運(yùn)行結(jié)果



      ?

      友情鏈接
      ioDraw流程圖
      API參考文檔
      OK工具箱
      云服務(wù)器優(yōu)惠
      阿里云優(yōu)惠券
      騰訊云優(yōu)惠券
      京東云優(yōu)惠券
      站點(diǎn)信息
      問題反饋
      郵箱:[email protected]
      QQ群:637538335
      關(guān)注微信

        <ul id="qxxfc"><fieldset id="qxxfc"><tr id="qxxfc"></tr></fieldset></ul>
          精品乱码一区二区三四区 | 潘金莲和武松做爰h | 高跟鞋操逼视频 | 国产探花精品在线 | 午夜无码成人福利 | 日本少妇做爰全过程 | 就去干成人网 | 伦理一区二区三区 | 小香蕉日韩视频 | 成人AV片导航 |