C#高级编程,关键词是泛型,泛型方法,泛型委托
时间:2011-01-29 来源:snowlueng
玩C#这免不了要搞它的特性,泛型我觉得是C#最有趣的地方。泛型让C#程序更加灵活。
引用MSDN上的话:
泛型是 2.0 版 C# 语言和公共语言运行库 (CLR) 中的一个新功能。泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法成为可能:这些类和方法将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法的时候。例如,通过使用泛型类型参数 T,您可以编写其他客户端代码能够使用的单个类,而不致引入运行时强制转换或装箱操作的成本或风险。
红色字是亮点。估计也是泛型的最大好处了。
既然引用了,不妨把代码也扔进来吧。
- // Declare the generic class
- public class GenericList<T>
- {
- void Add(T input) { }
- }
- class TestGenericList
- {
- private class ExampleClass { }
- static void Main()
- {
- // Declare a list of type int
- GenericList<int> list1 = new GenericList<int>();
- // Declare a list of type string
- GenericList<string> list2 = new GenericList<string>();
- // Declare a list of type ExampleClass
- GenericList<ExampleClass> list3 = new GenericList<ExampleClass>();
- }
- }
概念解释到这里吧。
下面就是我理解这个东西的时候,写的一些帮助理解的代码。这个代码在C#高级编程里面也有。
情景:
我要计算我家里所有人的收入的总和。
分析:
IPerson (主要用来展示泛型方法)
MyFamilyPerson :IPerson(IPerson的一个子类)
MyFamilyManage (计算收入总和的逻辑类)
下面先上源代码,再分析。
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace SnowSolution
- {
- class Program
- {
- /// <summary>
- /// 泛型委托用
- /// </summary>
- /// <typeparam name="TPerson"></typeparam>
- /// <typeparam name="TSummary"></typeparam>
- /// <param name="tp"></param>
- /// <param name="ts"></param>
- /// <returns></returns>
- delegate TSummary DelegateSummaryMoney<TPerson, TSummary>(TPerson tp, TSummary ts);
- static void Main(string[] args)
- {
- List<MyFamilyPerson> family = new List<MyFamilyPerson>();
- family.Add(new MyFamilyPerson("Father", 10000));
- family.Add(new MyFamilyPerson("Mother", 2345));
- MyFamilyManage fctrl = new MyFamilyManage();
- #region 泛型方法实现
- decimal sum1 = fctrl.SummaryMoney(family);
- Console.WriteLine(sum1);
- Console.ReadKey();
- #endregion
- #region 泛型委托实现
- decimal sum2 = fctrl.SummaryMoney<MyFamilyPerson,decimal> (family, delegate(MyFamilyPerson f,decimal s)
- {
- return f.money + s;
- });
- Console.WriteLine(sum2);
- Console.ReadKey();
- #endregion
- }
- interface IPerson
- {
- string name { get; }
- decimal money { get;}
- }
- class MyFamilyPerson : IPerson
- {
- public MyFamilyPerson(string n,decimal m)
- {
- this.mm = m;
- this.nn = n;
- }
- #region IPerson 成员
- private string nn;
- public string name
- {
- get { return nn; }
- }
- private decimal mm;
- public decimal money
- {
- get { return mm; }
- }
- #endregion
- }
- class MyFamilyManage
- {
- /// <summary>
- /// 泛型方法
- /// </summary>
- /// <typeparam name="TPerson"></typeparam>
- /// <param name="p"></param>
- /// <returns></returns>
- public decimal SummaryMoney<TPerson>(IEnumerable<TPerson> p)
- where TPerson :IPerson
- {
- decimal sum = 0;
- foreach (TPerson pm in p)
- {
- sum += pm.money;
- }
- return sum;
- }
- /// <summary>
- /// 泛型委托
- /// </summary>
- /// <typeparam name="TPerson"></typeparam>
- /// <typeparam name="TSummary"></typeparam>
- /// <param name="p"></param>
- /// <param name="method"></param>
- /// <returns></returns>
- public TSummary SummaryMoney<TPerson, TSummary>(IEnumerable<TPerson> p, DelegateSummaryMoney<TPerson, TSummary> method)
- {
- TSummary sum = default(TSummary);
- foreach (TPerson pm in p)
- {
- sum = method(pm, sum);
- }
- return sum;
- }
- }
- }
- }
对于泛型方法的实现。
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);
- decimal sum2 = fctrl.SummaryMoney<MyFamilyPerson,decimal> (family, delegate(MyFamilyPerson f,decimal s)
- {
- return f.money + s;
- });
public TSummary SummaryMoney<TPerson, TSummary>(IEnumerable<TPerson> p, DelegateSummaryMoney<TPerson, TSummary> method)
{....}
请看上述代码。
泛型委托,先定义委托,写好所有的泛型,如TSummary,TPerson,按本例子的情景来说,TSummary就是总和,TPerson就是人。这个做法让计算逻辑放到了你想放到的地方去,正如上面的匿名方法。这可以实现你想要的任何计算逻辑(我不算总和了,我算乘积,我算余数,我算……都行)。而且这个没有类型限制,可以按你所写的实现函数(本文是匿名函数)的逻辑去完成需要的计算,也就不局限于用什么类了。
这样的好处:1、有泛型方法的所有好处。2、克服了泛型方法的坏处。
坏处:把计算逻辑又提到客户类去了……(可以再封装,不算坏处。)
好了,写完了,下一次写应该是集合了。
睡觉,改天再看那砖头书。
如果你想了解一下委托,可以搜索blog里面的战斗机实现委托。
对本文有建议或意见请直接留言哈