Generic(泛型)

什么是泛型:“通过参数化类型来实现在同一份代码上操作多种数据类型。利用“参数化类型”将类型抽象化,从而实现灵活的复用”。

简单来说泛型就是为了使一些代码能够重复利用。

泛型的经历:

在早期.net框架中不同的参数类型需要声明不同的方法;

 1   public class CommonMethod
 2     {
 3         /// <summary>
 4         /// 打印个int值
 5         /// </summary>
 6         /// <param name="iParameter"></param>
 7         public static void ShowInt(int iParameter)
 8         {
 9             Console.WriteLine("This is {0},parameter={1},type={2}",
10                 typeof(CommonMethod).Name, iParameter.GetType().Name, iParameter);
11         }
12 
13         /// <summary>
14         /// 打印个string值
15         /// </summary>
16         /// <param name="sParameter"></param>
17         public static void ShowString(string sParameter)
18         {
19             Console.WriteLine("This is {0},parameter={1},type={2}",
20                 typeof(CommonMethod).Name, sParameter.GetType().Name, sParameter);
21         }
22 
23         /// <summary>
24         /// 打印个DateTime值
25         /// </summary>
26         /// <param name="oParameter"></param>
27         public static void ShowDateTime(DateTime dtParameter)
28         {
29             Console.WriteLine("This is {0},parameter={1},type={2}",
30                 typeof(CommonMethod).Name, dtParameter.GetType().Name, dtParameter);
31         }
32 }
View Code

 

后来开发人员觉得这样声明太麻烦了,提出了Object参数来替代,因为

1 任何父类出现的地方,都可以使用子类来替换
2 object是一切类型的父类

 1         /// <summary>
 2         /// 打印个object值
 3         /// 1 任何父类出现的地方,都可以使用子类来替换
 4         /// 2 object是一切类型的父类
 5         /// </summary>
 6         /// <param name="oParameter"></param>
 7         public static void ShowObject(object oParameter)
 8         {
 9             //((People)tParameter).Id
10             Console.WriteLine("This is {0},parameter={1},type={2}",
11                 typeof(CommonMethod), oParameter.GetType().Name, oParameter);
12         }
13     }
View Code

但是声明object参数方法调用时会经常的进行装箱拆箱,这样会影响程序的运行效率。

后来在.net2.0框架中引用的泛型的概念,这就是泛型的由来。

 1  public class GenericMethod
 2     {
 3         /// <summary>
 4         /// </summary>
 5         /// <typeparam name="T"></typeparam>
 6         /// <param name="tParameter"></param>
 7         public static void Show<T>(T tParameter)
 8         {
 9             Console.WriteLine("This is {0},parameter={1},type={2}",
10                 typeof(GenericMethod), tParameter.GetType().Name, tParameter.ToString());
11         }
12 }
View Code

泛型的思想: 延迟声明,把参数类型的声明推迟到调用

但是单单这样声明一个泛型方法是有缺陷的,比如说声明一个people对象,想打印出people的属性,单声明一个泛型方法是做不到这个功能的。

1 public class People
2     {
3         public int Id { get; set; }
4         public string Name { get; set; }
5 
6         public void Hi()
7         { }
8 
9     }
View Code

不信的可以用上面的泛型方法试试,只会出现object下的方法。

这就出现了泛型约束。

泛型约束:它通知编译器,只有这个类型的对象或从这个类型派生的对象,可被用作类型参数。一旦编译器得到这样的保证,它就允许在泛型类中调用这个类型的方法。

按照我的理解就是说,定义了一个泛型后,然后声明一个约束,告诉这个方法是满足哪些条件的约束,这样才能直接使用基类的属性和方法

 public class Constraint
    {
        /// <summary>
        /// 泛型约束,基类约束:
        /// 1 在泛型方法内可以直接使用基类的属性和方法
        /// 2 调用的时候,只能传递基类或者基类的子类
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tParameter"></param>
        public static void Show<T>(T tParameter) where T : People
        {
            Console.WriteLine("This is {0},parameter={1},type={2}",
                typeof(GenericMethod), tParameter.GetType().Name, tParameter.ToString());
            //((People)tParameter).Id
            //tParameter.
            Console.WriteLine("id={0} name={1}", tParameter.Id, tParameter.Name);
            tParameter.Hi();

}

泛型约束分为下面几种:

约束

描述

where T: struct

类型参数必须为值类型。 默认返回return default(T);

where T : class

类型参数必须为引用类型。默认返回return null;

where T : new()

类型参数必须有一个公有、无参的构造函数。当于其它约束联合使用时,new()约束必须放在最后。

where T : <base class name>

类型参数必须是指定的基类型或是派生自指定的基类型。

where T : <interface name>

类型参数必须是指定的接口或是指定接口的实现。可以指定多个接口约束。接口约束也可以是泛型的。

 

还有一些关于泛型类、接口、委托的声明。
public class GenericClass<T>
    {

        public void Show(T t)
        {
            Console.WriteLine(t);
        }

     

        public T Get(T t)
        {
            List<int> iList = null;
            return t;
        }
    }

    public interface IGet<T>
    { }

    public delegate void GetHandler<T>();
}

  

posted on 2017-06-24 22:10  西码  阅读(245)  评论(0编辑  收藏  举报