<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
        

      C#基礎系列——委托實現簡單設計模式

      前言:上一篇介紹了下多線程的相關知識:C#基礎系列——多線程的常見用法詳解,里面就提到了委托變量。這篇簡單介紹下委托的使用。當然啦,園子里面很多介紹委托的文章都會說道:委托和事件的概念就像一道坎,過了這個檻的人,覺得真是太容易了,而沒有過去的人每次見到委托和事件就覺得心里發慌。確實這東西就像最開始學C語言的指針一樣,令人有一種很糾結的感覺,總覺得要調用一個方法直接調用就行了,為啥非要定義一個委托時執行這個方法呢。其實在C#里面很多的技術都是為了重用和簡化代碼而生,委托也不例外,很多使用C#多態去實現的設計模式其實都可以使用委托的方式去改寫,可以理解為一種輕量級的設計模式吧。博主打算抽一篇專門分享下多態和委托實現設計模式的異同。這篇就先介紹簡單委托的使用。

       

      一、什么是委托:C# 中的委托(Delegate)類似于 C 或 C++ 中函數的指針。用博主的話說,委托就是一種允許將方法名稱作為參數傳遞的引用類型。它定義的是方法的類型,可以說就是方法的抽象,那么反過來說,方法可以理解為委托的實例,如public delegate void TestDelegate(string str);這種委托定義的就是所有參數類型為string,沒有返回值的方法的一種抽象。

       

      二、為什么要使用委托:記得博主剛開始做項目的時候看到委托的寫法就頭大,總覺得這是沒事找事,唯一的好處貌似就是代碼看上去很酷~~隨著工作的累積,發現項目中某些小的需求使用這種輕量級的委托來實現的時候確實能減少很多代碼量。

       

      三、委托的使用:

      1、.Net Framework 里面的委托類型:使用過委托的朋友可能注意到了C#里面定義了兩種類型的委托變量,基本能滿足我們的一般需求。

      (1)Action類型的委托:C#里面定義Action委托用于抽象化那種沒有返回值的方法。將Action變量轉到定義可知它的最簡單形式:

          // 摘要: 
          //     封裝一個方法,該方法不具有參數并且不返回值。
          [TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]
          public delegate void Action();

      它定義是就是一種沒有返回值沒有參數的委托。同時Action還提供了16個泛型的委托,用于定義方法的傳入參數:

       

       

      我們來看他們的使用方法,我們首先定義測試的方法:

              private static void Test5(int a, int b, int c)
              { 
                  //......
              }
      
      
              //無參數無返回值
              private static void Test1()
              {
                  Console.WriteLine("Func Test1, No Parameter");
              }
      
              //有參數無返回值
              private static void Test2(string str)
              {
                  Console.WriteLine("Func Test2, Parameter is" + str);
              }
      
              //無參數有返回值
              private static object Test3()
              {
                  Console.WriteLine("Func Test3, Parameter");
                  return Guid.NewGuid().ToString();
              }
      
              //有參數有返回值
              private static object Test4(string strRes)
              {
                  Console.WriteLine("Func Test4,  Parameter and Return Value");
                  return strRes;
              }

      調用:

              static void Main(string[] args)
              {
                  //1.無參無返回值方法
                  var oAction1 = new Action(Test1);
                  oAction1.Invoke();//調用方式一
                  oAction1();//調用方式二
      
                  //2.有參無返回值
                  var oAction2 = new Action<int, int, int>(Test5);
                  oAction2.Invoke(1, 2, 3);
                  oAction2(1, 2, 3);
                  //匿名方法的調用
                  var oAction3 = new Action<int, int, int>((a,b,c) => { 
                      //......
                  });
                  oAction3.Invoke(1, 2, 3);
             }

       

      (2)Func類型的委托:還記得Linq里面的擴展方法Where()、Select()等方法的參數嗎。public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)。這里的參數就是一個Func類型的委托。C#里面Func類型的委托用于處理有參數有返回值的方法。不多說,上代碼:

           static void Main(string[] args)
           {
                  var oFunc1 = new Func<object>(Test3);
                  var ofuncRes1 = oFunc1.Invoke();
                  var oFunc2 = new Func<string, object>(Test4);
                  oFunc2("a");    
           }

      知道了Func的方法就可以推想到我們神奇的lamada表達式了,其實lamada表達式就是一個匿名的委托。

      var lstTest = new List<string>();
      var lstRes = lstTest.Where(x => x.Contains("_"));

      這個Where里面的lamada表達式我們把他拆解:

      private static bool TestWhere(string x)
      {
           return x.Contains("_");
      }
      var oFunc = new Func<string, bool>(TestWhere);
      lstRes = lstTest.Where(oFunc);

      是不是一樣一樣的~~ 

       

      2、自定義委托:

      public delegate void TestDelegate(string str);

      其實很多人應該都自己寫過Action、Func類型的委托。其實自己定義一個泛型委托也很簡單:

      public delegate void MyAction<in T>();
      public delegate TResult MyFunc<in T, out TResult>(T arg);

      其實使用起來和系統的Action和Func基本沒有區別。

       

      3、委托的合并和拆解就放在事件里面分享了。這篇且過之。。。

       

      4、如果按照上面的方法去使用委托,那真的是要別扭死人了,因為調用方法直接用方法名調用就好了,何必還要定義一個委托變量去調用,這不是將簡單問題復雜化么。確實,上面只是為了介紹委托而寫的代碼,實際項目中肯定不會這么用。其實委托在項目中一般用在將委托變量作為參數傳遞或者函數回調。來看下面代碼:

         class Program
          {
              static void Main(string[] args)
              {
                  
                  Person strHelper = new Person();
                  string r1 = strHelper.ProcessFunc("中國人", "你好", new MyDelegate(strHelper.ChineseSayHello));
                  string r2 = strHelper.ProcessFunc("English", "Hello", new MyDelegate(strHelper.EnglishSayHello));
                  string r3 = strHelper.ProcessFunc("Japanese", "こんにちは", new MyDelegate(strHelper.JapaneseSayHello));
      
                  Console.WriteLine(r1);
                  Console.WriteLine(r2);
                  Console.WriteLine(r3);
      
                  Console.ReadKey();
              }
      
          }
      
          public delegate string MyDelegate(string s1, string s2);
          public class Person
          {
              public string ProcessFunc(string s1, string s2, MyDelegate process)
              {
                  return process(s1, s2);
              }
      
              public string ChineseSayHello(string s1, string s2)
              {
                  return s1 +","+ s2;
              }
      
              public string EnglishSayHello(string s1, string s2)
              {
                  return s1 + "," + s2;
              }
      
              public string JapaneseSayHello(string s1, string s2)
              {
                  return s1 +","+ s2;
              }
          }

      得到結果:

      public string ProcessFunc(string s1, string s2, MyDelegate process)里面定義了一個回調函數,可以將任意一個符合這個委托的方法傳遞進去,得到想對應的結果。細看這種設計是不是和工廠設計模式十分相似,我簡單構造了個工廠:

      public class Person
          {
              public virtual string SayHello(string s2)
              {
                  return s2;
              }
          }
      public class Chinese : Person
          {
              public override string SayHello(string s2)
              {
                  return "中國人," + s2;
              }
          }
      
          public class English : Person
          {
              public override string SayHello(string s2)
              {
                  return "English," + s2;
              }
          }
      
          public class Japanese : Person
          {
              public override string SayHello(string s2)
              {
                  return "Japanese," + s2;
              }
          }
      
      
      //Main函數里面調用
      class Program
          {
              static void Main(string[] args)
              {
                  var r1 = GetPerson("你好").SayHello("你好");
                  var r2 = GetPerson("Hello").SayHello("Hello");
                  var r3 = GetPerson("こんにちは").SayHello("こんにちは");
                  Console.WriteLine(r1);
                  Console.WriteLine(r2);
                  Console.WriteLine(r3);
      
                  Console.ReadKey();
              }
      
              public static Person GetPerson(string strType)
              {
                  if (strType == "你好")
                      return new Chinese();
                  else if (strType == "Hello")
                      return new English();
                  else
                      return new Japanese();
              }
              
          }

      得到結果和上面相同:

      這樣一比較是不是對委托的用法有點感覺了呢~~如果你不怕麻煩,可以在項目是用起來試試,相信你會有收獲~~

      示例下載

       

      posted @ 2015-08-06 15:42  懶得安分  閱讀(10307)  評論(11)    收藏  舉報
      主站蜘蛛池模板: 国产99久久无码精品| 一区天堂中文最新版在线| 国产一区二区三区不卡观| 国产激情艳情在线看视频| 茄子视频国产在线观看| 天堂网亚洲综合在线| 国产一区二区三区在线看| 欧美午夜成人片在线观看| 麻豆精品一区二区综合av| 色综合 图片区 小说区| 国产特色一区二区三区视频| 亚洲一区二区偷拍精品| 亚洲色大成网站WWW久久| 一区二区三区在线 | 欧洲| 正在播放国产剧情亂倫| 云阳县| 国产超高清麻豆精品传媒麻豆精品 | 国内久久人妻风流av免费| 亚洲真人无码永久在线| 亚洲高潮喷水无码AV电影| 国产精品人一区二区三区| 中文字幕在线不卡一区二区| 精品国产免费一区二区三区香蕉| 欧美性猛交xxxx乱大交丰满| 亚洲AV国产福利精品在现观看| 精品国产乱码久久久久APP下载| 丁香五月婷激情综合第九色 | 日夜啪啪一区二区三区| 黑人猛精品一区二区三区| 亚洲精品久久婷婷丁香51| 亚洲男人第一无码av网站| 熟女精品视频一区二区三区| 制服jk白丝h无内视频网站| 亚洲欧美综合人成在线| 亚洲国产成人久久综合区| 人妻少妇精品中文字幕| 日本一区二区不卡精品| 亚洲丰满老熟女激情av| 别揉我奶头~嗯~啊~的视频| 日韩精品一区二区蜜臀av| 亚洲国家av一区二区|