能否给我举个列子,我看了很多概念,稍有了解,但还是不太明白,能否举个例子来说说
泛型在写时是不是在定义class时写还是也可以在方法里写。

解决方案 »

  1.   

    泛型类的声明
    class class-name<type-param-list>{}
    声明一个对泛型类的应用的语法格式
    class-name<type-arg-list> var-name=new class-name<type-arg-list>(constaint-arg-list);
    在指定一个类型参数时,可以指定类型参数必须满足的约束条件。这里通过在指定类型参数时使用where子句来实现,其中constaints时一个逗号分割的约束列表。
    class classname<type-param-list> where type-param:constaints{}
    1、可以通过使用"基类约束(base class constraint)"来指定某个基类必须出现在类型实参中。这种约束是通过指定基类名称来实现的。
    2、可以使用"接口约束(interface constraint)"来指定某个类型实参必须实现一个或多个接口。这种约束是通过指定接口名称来实现的。
    3、可以要求类型实参必须提供一个无参数的构造函数,这被称为"构造函数约束(constuctor constraint)"。它是通过new()指定的。
    4、可以通过关键字class指定"引用类型约束(reference type constraint)"来限制某个类型实参必须是引用类型。
    5、可以通过关键字struct指定"值类型约束(value type constraint)"来限制某个类型实参必须是值类型。
    new()构造函数约束允许开发人员实例化一个泛型类型的对象。
    一般情况下,我们无法创建一个泛型类型参数的实例。然后,new()约束改变了这种情况,他要求类型参数必须提供一个无参数的构造函数。
    在使用new()约束时,可以通过调用该无参数构造函数来创建对象。
    where type-parma:new()
    使用new()约束时应注意两点:
    1、它可以与其它约束一起使用,但是必须位于约束列表的末端;
    2、new()仅允许开发人员使用无参数构造函数来构造一个对象,即使同时存在其它的构造函数。换句话说,不允许给类型参数的构造函数传递参数。
    若同时存在其它约束,class或struct必须位于列表的开头。
    where:type-param:class/struct
    可以通过使用约束来建立两个类型参数之间的关系
    class GenericClass<T,V> where V:T{}  要求V必须继承于T,这种类型的约束称为裸类型约束(naked type constraint)。
    使用泛型类:
    在给泛型类传递参数类型实参的时候,实际创建的是C#中的"封闭构建类型(closed constructed type)"。
    术语"封闭"一词,是指指定了类型实参,因此GenericClass<int>是一个封闭构建类型。本质上,泛型类型,例如GenericClass<T>,是一种抽象构造。只有在特定的版本(例如GenericClass<int>)被创建以后才创建了一个实际的类型。
    在C#中,GenericClass<T>之类的构造被称为"开放构建类型(open constucted type)",是因为它没有指定类型实参。
    abstract类只能含有方法签名,不包含方法实现;abstract方法只能出现在抽象类中。泛型实现 表面上,C# 泛型的语法看起来与 C++ 模板类似,但是编译器实现和支持它们的方式存在重要差异。正如您将在后文中看到的那样,这对于泛型的使用方式具有重大意义。 注 在本文中,当提到 C++ 时,指的是传统 C++,而不是带有托管扩展的 Microsoft C++。与 C++ 模板相比,C# 泛型可以提供增强的安全性,但是在功能方面也受到某种程度的限制。 在一些 C++ 编译器中,在您通过特定类型使用模板类之前,编译器甚至不会编译模板代码。当您确实指定了类型时,编译器会以内联方式插入代码,并且将每个出现一般类型参数的地方替换为指定的类型。此外,每当您使用特定类型时,编译器都会插入特定于该类型的代码,而不管您是否已经在应用程序中的其他某个位置为模板类指定了该类型。C++ 链接器负责解决该问题,并且并不总是有效。这可能会导致代码膨胀,从而增加加载时间和内存足迹。 在 .NET 2.0 中,泛型在 IL(中间语言)和 CLR 本身中具有本机支持。在编译一般 C# 服务器端代码时,编译器会将其编译为 IL,就像其他任何类型一样。但是,IL 只包含实际特定类型的参数或占位符。此外,一般服务器的元数据包含一般信息。 客户端编译器使用该一般元数据来支持类型安全。当客户端提供特定类型而不是一般类型参数时,客户端的编译器将用指定的类型实参来替换服务器元数据中的一般类型参数。这会向客户端的编译器提供类型特定的服务器定义,就好像从未涉及到泛型一样。这样,客户端编译器就可以确保方法参数的正确性,实施类型安全检查,甚至执行类型特定的 IntelliSense。 有趣的问题是,.NET 如何将服务器的一般 IL 编译为机器码。原来,所产生的实际机器码取决于指定的类型是值类型还是引用类型。如果客户端指定值类型,则 JIT 编译器将 IL 中的一般类型参数替换为特定的值类型,并且将其编译为本机代码。但是,JIT 编译器会跟踪它已经生成的类型特定的服务器代码。如果请求 JIT 编译器用它已经编译为机器码的值类型编译一般服务器,则它只是返回对该服务器代码的引用。因为 JIT 编译器在以后的所有场合中都将使用相同的值类型特定的服务器代码,所以不存在代码膨胀问题。 如果客户端指定引用类型,则 JIT 编译器将服务器 IL 中的一般参数替换为 Object,并将其编译为本机代码。在以后的任何针对引用类型而不是一般类型参数的请求中,都将使用该代码。请注意,采用这种方式,JIT 编译器只会重新使用实际代码。实例仍然按照它们离开托管堆的大小分配空间,并且没有强制类型转换。 泛型的好处 .NET 中的泛型使您可以重用代码以及在实现它时付出的努力。类型和内部数据可以在不导致代码膨胀的情况下更改,而不管您使用的是值类型还是引用类型。您可以一次性地开发、测试和部署代码,通过任何类型(包括将来的类型)来重用它,并且全部具有编译器支持和类型安全。因为一般代码不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。对于值类型,性能通常会提高 200%;对于引用类型,在访问该类型时,可以预期性能最多提高 100%(当然,整个应用程序的性能可能会提高,也可能不会提高)。本文随附的源代码包含一个微型基准应用程序,它在紧密循环中执行堆栈。该应用程序使您可以在基于 Object 的堆栈和一般堆栈上试验值类型和引用类型,以及更改循环迭代的次数以查看泛型对性能产生的影响。
      

  2.   

    可以获得类型安全 
    不需要从基集合类型派生并实现类型特定的成员
    http://topic.csdn.net/u/20090622/21/df7f7b8a-61cd-4c8f-a964-0fe15377523d.html