一. 泛型诞生的背景

  在介绍背景之前,先来看一个案例,要求:分别输出实体model1、model2、model3的id和name值,这三个实体有相同的属性名字id和name。

 1  public class myUtils
 2     {
 3         //要求:分别输出实体model1、model2、model3的id和name值,这三个实体有相同的属性名字id和name
 4 
 5         //传统的解决方案(一):由于三个不同的实体,所以要声明三个不同的方法来输出
 6         /*
 7         缺点:该解决方案十分繁琐,明明相同的属性,不得不声明三个不同的方法,造成代码的大量冗余
 8         */
 9 
10         public static void showM1(model1 m1)
11         {
12             Console.WriteLine("id值为:" + m1.id + "  name值为:" + m1.name);
13         }
14 
15         public static void showM2(model2 m2)
16         {
17             Console.WriteLine("id值为:" + m2.id + "  name值为:" + m2.name);
18         }
19 
20         public static void showM3(model3 m3)
21         {
22             Console.WriteLine("id值为:" + m3.id + "  name值为:" + m3.name);
23         }
24 
25 
26         //传统的解决方案(二):使用Object类型来解决该问题
27         //原理:object是所有类型的父类,所有用到父类的地方都可以用子类去代替,即:里氏替换原则
28         /*
29              缺点:需要记住可能会传进来哪几种类型;最大的问题是值类型和引用类型之间的互换(即拆箱和装箱)严重影响性能
30          */
31 
32         public static void showObj(object obj)
33         {
34             if (obj.GetType() == typeof(model1))
35             {
36                 model1 m = (model1)obj;
37                 Console.WriteLine("id值为:" + m.id + "  name值为:" + m.name);
38             }
39             else if (obj.GetType() == typeof(model2))
40             {
41                 model2 m = (model2)obj;
42                 Console.WriteLine("id值为:" + m.id + "  name值为:" + m.name);
43             }
44             else if (obj.GetType() == typeof(model3))
45             {
46                 model3 m = (model3)obj;
47                 Console.WriteLine("id值为:" + m.id + "  name值为:" + m.name);
48             }
49 
50         }
51 
52         //基于以上两种传统的解决方案都缺点明显,所以在 .Net 2.0的时候,推出了一个通用语言运行时(CRL)的新特性即:泛型。
53         /*
54             泛型为.NET框架引入了类型参数(type parameters)的概念。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。
55             这意味着使用泛型的类型参数T,可以多种形式调用,运行时类型转换避免了装箱操作的代价和风险。
56 
57          */
58        
59     }

  基于以上两种传统的解决方案都缺点明显,所以在 .Net 2.0的时候,推出了一个通用语言运行时(CLR)的新特性即:泛型。泛型为.NET框架引入了类型参数(type parameters)的概念,它属于System.Collections.Generic命名空间下。类型参数使得设计类和方法时,不必确定一个或多个具体参数,其的具体参数可延迟到客户代码中声明、实现。

  这意味着使用泛型的类型参数T,可以多种形式调用,运行时类型转换避免了装箱操作的代价和风险。

二. 泛型的引入

   为了解决上述问题,我们这里引入泛型的概念来解决代码冗余的问题和性能低下的问题。

  这里统一说明一下:model1、model2、model3实体均继承与ModelFather实体,ModelFather实体中有两个属性,id和name,下同。 

 1        /// <summary>
 2         /// 泛型方法的引入
 3         /// </summary>
 4         /// <typeparam name="T">T为泛型的一个标记,也可以用别的字母代替</typeparam>
 5         /// <param name="t"></param>
 6         public static void showModel<T>(T t)
 7         {
 8             Console.WriteLine(t);
 9         }
10 
11         /// <summary>
12         /// 泛型约束的引入,如果要输出实体中的值,需要配合“基类约束”方可以实现
13         /// </summary>
14         /// <typeparam name="T"></typeparam>
15         /// <param name="t"></param>
16         public static void showModelDetils<T>(T t) where T : ModelFather
17         {
18             Console.WriteLine("id值为:" + t.id + "  name值为:" + t.name);
19         }
20 
21 
22         //总结:
23         /*
24             1. 以上两个方法均为泛型方法,T代表的类型在使用时才声明,俗称“延迟声明”。
25             2. 如果要使用类中的属性时,需要配合泛型的“基类约束”来实现
26         */

  总结:

    1. 以上两个方法均为泛型方法,T代表的类型在使用时才声明,俗称“延迟声明”。

    2. 如果要使用类中的属性时,需要配合泛型的“基类约束”来实现。

        说明:除了泛型方法外,还有泛型接口、泛型委托等,同样泛型约束除了“基类约束”外,还有其他约束。

三. 泛型的种类

  泛型包括:泛型方法、泛型类、泛型接口、泛型委托四类。

  这里主要介绍泛型方法,在后续会配合泛型的五种约束继续深入介绍。

 1 /// <summary>
 2     /// 泛型方法
 3     /// </summary>
 4     public class GenericsMethord
 5     {
 6         //这里介绍泛型方法,在之前02-泛型的引入中,使用的就是泛型方法,这里再重复一次
 7         /*
 8         详解:T为泛型的一个代表,换成别的字母同样可以
 9               T和A代表的类型在使用时才声明,俗称“延迟声明”
10         */
11         public static void ShowModel<T, A>(T model1, A model2)
12             where T : ModelFather
13             where A : model3
14         {
15             Console.WriteLine("id值为:" + model1.id + "  name值为:" + model1.name);
16             Console.WriteLine("id值为:" + model2.id + "  name值为:" + model2.name);
17         }
18     }
View Code

相关文章: