C#高級編程,關鍵詞是泛型,泛型方法,泛型委託

 用場景記憶法來記住這些東西就好。本文比較長,所以要看請耐心哈。

玩C#這免不了要搞它的特性,泛型我覺得是C#最有趣的地方。泛型讓C#程序更加靈活。

引用MSDN上的話:

泛型是 2.0 版 C# 語言和公共語言運行庫 (CLR) 中的一個新功能。泛型將類型參數的概念引入 .NET Framework,類型參數使得設計如下類和方法成爲可能:這些類和方法將一個或多個類型的指定推遲到客戶端代碼聲明並實例化該類或方法的時候。例如,通過使用泛型類型參數 T,您可以編寫其他客戶端代碼能夠使用的單個類,而不致引入運行時強制轉換或裝箱操作的成本或風險

紅色字是亮點。估計也是泛型的最大好處了。

既然引用了,不妨把代碼也扔進來吧。

  1. // Declare the generic class 
  2. public class GenericList<T> 
  3.     void Add(T input) { } 
  4. class TestGenericList 
  5.     private class ExampleClass { } 
  6.     static void Main() 
  7.     { 
  8.         // Declare a list of type int 
  9.         GenericList<int> list1 = new GenericList<int>(); 
  10.  
  11.         // Declare a list of type string 
  12.         GenericList<string> list2 = new GenericList<string>(); 
  13.  
  14.         // Declare a list of type ExampleClass 
  15.         GenericList<ExampleClass> list3 = new GenericList<ExampleClass>(); 
  16.     } 

概念解釋到這裏吧。

下面就是我理解這個東西的時候,寫的一些幫助理解的代碼。這個代碼在C#高級編程裏面也有。

情景:

我要計算我家裏所有人的收入的總和。

分析:

IPerson (主要用來展示泛型方法)

MyFamilyPerson :IPerson(IPerson的一個子類)

MyFamilyManage (計算收入總和的邏輯類)

下面先上源代碼,再分析。

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Text; 
  4.  
  5. namespace SnowSolution 
  6.     class Program 
  7.     { 
  8.         /// <summary> 
  9.         /// 泛型委託用 
  10.         /// </summary> 
  11.         /// <typeparam name="TPerson"></typeparam> 
  12.         /// <typeparam name="TSummary"></typeparam> 
  13.         /// <param name="tp"></param> 
  14.         /// <param name="ts"></param> 
  15.         /// <returns></returns> 
  16.         delegate TSummary DelegateSummaryMoney<TPerson, TSummary>(TPerson tp, TSummary ts); 
  17.  
  18.         static void Main(string[] args) 
  19.         { 
  20.             List<MyFamilyPerson> family = new List<MyFamilyPerson>(); 
  21.             family.Add(new MyFamilyPerson("Father", 10000)); 
  22.             family.Add(new MyFamilyPerson("Mother", 2345)); 
  23.             MyFamilyManage fctrl = new MyFamilyManage(); 
  24.  
  25.  
  26.  
  27.             #region 泛型方法實現 
  28.             decimal sum1 = fctrl.SummaryMoney(family); 
  29.             Console.WriteLine(sum1); 
  30.             Console.ReadKey(); 
  31.             #endregion  
  32.  
  33.  
  34.             #region 泛型委託實現 
  35.             decimal sum2 = fctrl.SummaryMoney<MyFamilyPerson,decimal> (family, delegate(MyFamilyPerson f,decimal s) 
  36.             { 
  37.                 return f.money + s; 
  38.             }); 
  39.             Console.WriteLine(sum2); 
  40.             Console.ReadKey(); 
  41.             #endregion 
  42.         } 
  43.         interface IPerson  
  44.         { 
  45.             string name { get; } 
  46.             decimal money { get;} 
  47.         } 
  48.         class MyFamilyPerson : IPerson 
  49.         { 
  50.             public MyFamilyPerson(string n,decimal m)  
  51.             { 
  52.                 this.mm = m; 
  53.                 this.nn = n; 
  54.             } 
  55.  
  56.             #region IPerson 成員 
  57.             private string nn; 
  58.             public string name 
  59.             { 
  60.                 get { return nn; } 
  61.             } 
  62.             private decimal mm; 
  63.             public decimal money 
  64.             { 
  65.                 get { return mm; } 
  66.             } 
  67.  
  68.  
  69.             #endregion 
  70.         } 
  71.         class MyFamilyManage  
  72.         { 
  73.             /// <summary> 
  74.             /// 泛型方法 
  75.             /// </summary> 
  76.             /// <typeparam name="TPerson"></typeparam> 
  77.             /// <param name="p"></param> 
  78.             /// <returns></returns> 
  79.             public decimal SummaryMoney<TPerson>(IEnumerable<TPerson> p) 
  80.                 where TPerson :IPerson 
  81.             { 
  82.                 decimal sum = 0; 
  83.                 foreach (TPerson pm in p) 
  84.                 { 
  85.                     sum += pm.money; 
  86.                 } 
  87.  
  88.                 return sum; 
  89.             } 
  90.             /// <summary> 
  91.             /// 泛型委託 
  92.             /// </summary> 
  93.             /// <typeparam name="TPerson"></typeparam> 
  94.             /// <typeparam name="TSummary"></typeparam> 
  95.             /// <param name="p"></param> 
  96.             /// <param name="method"></param> 
  97.             /// <returns></returns> 
  98.             public TSummary SummaryMoney<TPerson, TSummary>(IEnumerable<TPerson> p, DelegateSummaryMoney<TPerson, TSummary> method) 
  99.             { 
  100.                 TSummary sum = default(TSummary); 
  101.  
  102.                 foreach (TPerson pm in p) 
  103.                 { 
  104.                     sum = method(pm, sum); 
  105.                 } 
  106.                 return sum; 
  107.             } 
  108.         } 
  109.     } 

對於泛型方法的實現。

public decimal SummaryMoney<TPerson>(IEnumerable<TPerson> p) 

where TPerson :IPerson

{....}

請看上述方法。

泛型方法:基本已經說明了MSDN上指出的好處了。定義一個TPerson,用於調用時傳入類,延遲了類的生成時間,而使用where關鍵詞,可以有效約束TPerson的類型。使得方法內可以使用所有支持IPerson的方法。

這樣的好處:可以滿足所有繼承IPerson的類的實現。對應的現實環境就是,不管你是中國人,美國人,只要支持IPerson接口,我都可以計算你家的所有人的收入總和。

這樣的缺點:不支持IPerson的則不可使用。對應現實環境是,如果不是地球人(火星?水星?)的話……

===============

對於泛型委託的實現。

delegate TSummary DelegateSummaryMoney<TPerson, TSummary>(TPerson tp, TSummary ts);

  1.   decimal sum2 = fctrl.SummaryMoney<MyFamilyPerson,decimal> (family, delegate(MyFamilyPerson f,decimal s) 
  2.             { 
  3.                 return f.money + s; 
  4.             }); 

public TSummary SummaryMoney<TPerson, TSummary>(IEnumerable<TPerson> p, DelegateSummaryMoney<TPerson, TSummary> method) 

{....}

請看上述代碼。

泛型委託,先定義委託,寫好所有的泛型,如TSummary,TPerson,按本例子的情景來說,TSummary就是總和,TPerson就是人。這個做法讓計算邏輯放到了你想放到的地方去,正如上面的匿名方法。這可以實現你想要的任何計算邏輯(我不算總和了,我算乘積,我算餘數,我算……都行)。而且這個沒有類型限制,可以按你所寫的實現函數(本文是匿名函數)的邏輯去完成需要的計算,也就不侷限於用什麼類了。

這樣的好處:1、有泛型方法的所有好處。2、克服了泛型方法的壞處。

壞處:把計算邏輯又提到客戶類去了……(可以再封裝,不算壞處。)

好了,寫完了,下一次寫應該是集合了。

睡覺,改天再看那磚頭書。

如果你想了解一下委託,可以搜索blog裏面的戰鬥機實現委託。

對本文有建議或意見請直接留言哈

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章