不平凡的泛型

随着集合的发展,我们使用集合的同时也发现集合的一些问题:由于类型的强制转换带来的类型安全问题,代码的复用率低,影响代码运行效率,比如:

 
            

所以为了避免上面的两个问题,.net2.0提出了泛型的概念。也就是泛型将类型参数的概念引入了 .net中,使用泛型可以最大限度得重用代码,保护类型的安全以及提高性能。

所谓泛型,就是通过参数化类型来实现在同一份代码上操作多种数据类型,它利用“参数化类型”将类型抽象化,使实现更为灵活地复用。

在泛型类或方法的定义中,类型参数是客户端代码在实例化泛型类型的变量时指定的特定类型的占位符。通常我们使用T作为类型参数占位符,但这并不是必须的,我们可以使用一些更有意义的描述性的名称作为类型占位符,如TInput 、TOutput等。

<span style="font-size:18px;"><span style="font-size:24px;">     public  class  List<TInput,TOutput></span></span>

但有些代码(如下),无法进行编译,为什么?因为我们没有对类型参数T进行类型的设置,这也就是我们通常所说的类型约束。

<span style="font-size:18px;"><span style="font-size:24px;">public class SortHelper<T>  : IComparable{

        public void BubbleSort(T[] array)
       {
           int length = array.Length;

            for (int i = 0; i <= length - 2; i++)
            {
               for (int j = length - 1; j >= 1; j--)
               {

                    // 对两个元素进行交换
                  if (array[j] < array[j - 1])
                   {
                       T temp = array[j];
                       array[j] = array[j - 1];
                       array[j - 1] = temp;
                   }
              }
         }</span></span>

所以,应用泛型约束的概念对上面的代码进行改善:

C#泛型要求对“所有泛型类型或泛型方法的类型参数”的任何假定,都要基于“显式的约束”,以维护C#所要求的类型安全。“显式约束”由where子句表达,而“显示约束”并非必须,如果没有指定的“显示约束”,泛型参数将只能访问System.object类型中的公有方法。

在定义泛型类型时可以对客户端代码在实例化类时用于类型参数的类型加以限制。约束使用where关键字来指定:

where T: struct 类型参数必须是值类型

where T: class 类型参数必须是引用类型

where T: new() 类型参数必须有一个 public 且无参数的构造函数

where T: <base classname> 类型参数必须继承至指定的基类(base class)

where T: <interface name> 类型参数必须是指定的接口或实现了指定接口的

       关于泛型的博客先总结到这里,都是个人理解,欢迎各位拍砖。

  

时间: 2024-11-08 02:10:08

不平凡的泛型的相关文章

Java泛型拾遗

先上百度百科的解释 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的好处是安全简单.在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的.对于强制类型转换错

.NET编程01(泛型)

一:Object 类型:一切类型的父类,通过继承,子类拥有父类一切属性和行为:任何父类出现的地方,都可以用子类来代替: 用一个方法来完成多个方法做的事 /// <summary>    /// 普通方法类    /// </summary>    public class CommonMethod    {        /// <summary>        /// 打印个int值        /// </summary>        /// <

c#系统泛型委托

Action<T> 无返回值的系统泛型委托 namespace ConsoleApp1 { public class UserInfo { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } class Program { private static List<UserInfo> getInit() { return new List<User

泛型2

万用字符(wildcard) 以动物Animal类为例,怎样才能创建出一种ArrayList<?>里面既可以保存ArrayList<Dog>,又可以保存ArrayList<Cat>? public void takeAnimals(ArrayList<? extends Animal> animals){  //泛型中extends同时代表继承和实现. for(Animal a : animals){ a.eat(); } } 我们可以这样调用该函数: Ar

通过反射了解集合泛型的本质

通过反射了解集合泛型的本质 import java.lang.reflect.Method; import java.util.ArrayList; /** * 通过反射了解集合泛型的本质 * @author shm * */ public class MethodDemo02 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("hello"); list.add(

构造方法中使用泛型

------------siwuxie095 构造方法中使用泛型: 构造方法可以为类中的属性初始化,如果类中的属性通过泛型指定,而又需要 通过构造方法设置属性内容的时候,构造方法的定义与之前并无不同,不需要 像声明类那样指定泛型 package com.siwuxie095.generic; class Context<T>{ private T value; public Context(T value) { this.value=value; } public T getValue() {

泛型委托当参数传递

假如有一个Person类: public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Title { get; set; } } 执行一个方法: /// <summary> /// 传递一个泛型委托方法 /// </summary> /// <param name="acti

类库,委托,is和as运算符,泛型集合

类库:其实就是一堆类文件,只不过用户看不到这些类的源代码,保密性好. 优点:保密性好缺点:如果这个方法不好用,使用者无法自己去更改它. 类文件是.cs    类库是.dll 新建项目为类库,在debug文件夹下找到dll文件 委托:委托可以理解为:函数的指针 关键词:delegate 声明委托类型:public delegate int FirstDel(int a, int b); FirstDel不是类,是委托变量,不能实例化(不能new), 创建委托变量:FirstDel 名字 = 与这个

泛型委托

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 泛型委托 { public delegate int DelCompare<T>(T t1, T t2); // public delegate int DelCompare(object o1, object o2); class Progra