zoukankan      html  css  js  c++  java
  • 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>();
    }
    

      

  • 相关阅读:
    Oracle 11g 在本机上安装PLSQL DEveloper
    Oracle 11g 启动与关闭服务的脚本
    Oracle 11g 安装过程图解
    linux下vi命令大全
    accuracy、precision、recall、true positives, true negatives, false positives 和 false negatives
    // 40、用1、2、2、3、4、5这六个数字,写一个main函数,打印出所有不同的排列, // 如:512234、412345等,要求:"4"不能在第三位,"3"与"5"不能相连.
    阿里巴巴第二道(研发类) 笔试题1,原题大致描述有一大批数据,百万级别的。数据项内容是:用户ID、科
    621. Task Scheduler
    625. Minimum Factorization
    623. Add One Row to Tree
  • 原文地址:https://www.cnblogs.com/xima/p/7074633.html
Copyright © 2011-2022 走看看