Visual C++ 中的泛型概述

泛型是公共语言运行时支持的参数化类型。 参数化的类型是定义与未知类型参数指定的类型,则使用泛型。

为什么普通?

C++ 支持模板,然后模板和泛型支持参数化类型创建类型化集合类。 但是,模板提供编译时进行参数化。 您不能引用包含模板定义的程序集和创建模板的新专用化。 在生成,一个专用的模板类似于其他类或方法。 相反,普通在 MSIL 发出,运行时已知的参数化的类型参数化的类型;引用包含泛型类型的程序集的源代码可以创建泛型类型的专用化。 有关 Visual C++ 模板和泛型的更多信息的比较,请 泛型和模板 (Visual C++)参见。

泛型函数和类型

类中,类型,前提是托管类型,可以为泛型。 此示例可能是 List 类。 一个对象的类型列表中的是类型参数。 如果需要对象的许多不同类型的 List 类,因此,在普通采用 System::Object 作为项目类型的可能已使用 List 之前。 ,但这将允许任何对象 (错误类型的包括对象) 用于列出。 此列表将调用非类型化集合类。 最好,可以检查该类型在运行时并引发异常。 或者,您可能已经使用了模板,将丢失其泛型质量一次编译到程序集中。 您的程序集的使用者不可创建自己的模板自己的专用化。 泛型允许您创建类型化集合类,指出将生成编译时错误的 List<int> (读取 “列表 int”) 和 List<double> (“列表二进制数据”),如果尝试放入集合尚未设计接受到类型化集合的类型。 此外,在中,以在生成后,这些类型保持泛型。

泛型类语法的说明。 泛型类 (C++/CLI). 的新命名空间, System.Collections.Generic能找到,引入了一组参数化的集合类型包括 Dictionary<TKey, TValue>List<T>LinkedList<T>。 有关更多信息,请参见.NET Framework 类库中的泛型(C# 编程指南)

实例和静态类成员函数,委托,并且,全局函数还为泛型。 泛型函数可能需要函数的参数是未知类型,或函数是否必须使用泛型类型一起使用。 在许多情况下 System::Object 能在过去作为参数为未知目标类型的情况下,泛型类型参数可以为更类型安全的代码,授权。 所有尝试将类型功能不会用于将标记为在编译时错误。 使用 System::Object 作为函数参数,函数不打算处理不会检测的意外通过对象和您必须将未知的对象类型到给定输入函数体,并考虑 InvalidCastException 的可能性。 泛型,尝试的代码传递给函数的对象将产生一个类型冲突,因此函数体确保具有正确的类型。

相同的优点应用于集合在普通生成的类。 集合类从前在集合将使用 System::Object 存储元素。 类型的对象插入集合未被设计为未标记在编译时,且经常不,即使已插入对象。 通常,那么,当该集合,访问了对象将转换为其他类型。 ,才显示该转换失败将检测意外类型。 泛型来解决此问题在编译时将检测插入类型不匹配的所有代码 (或隐式转换为) 泛型集合的类型参数。

有关语法的说明,请参见 泛型函数 (C++/CLI)

使用泛型术语

c570k3f3.collapse_all(zh-cn,VS.110).gif类型参数

泛型声明包含称为 " 类型的一个或多个未知类型参数。 命名委托在泛型声明的主体内类型参数的名称。 该类型参数用作在泛型声明的主体内为类型。 列表的 <T> 通用描述包含类型参数 T。

c570k3f3.collapse_all(zh-cn,VS.110).gif键入参数

,在泛型为特定类型或类型时,专用该 类型参数 是在该类型使用的实际类型参数位置。 例如, int 是在 List<int>的类型参数。 值类型和句柄类型是泛型类型允许的唯一类型参数。

c570k3f3.collapse_all(zh-cn,VS.110).gif构造类型

从泛型类型构造的类型称为构造 类型。 类型不完全指定,例如 List<T> 是开放式 构造的类型;类型是完全指定,例如 List<double>, 是一个 封闭式构造类型 或专用 类型。 打开构造的类型可用于其他泛型类型或方法,并且不能完全指定,直到封闭泛型自身的定义中指定。 例如,下面是一个打开的构造类型的用作泛型基类:

// generics_overview.cpp

// compile with: /clr /c

generic <typename T>

ref class List {};

generic <typename T>

ref class Queue : public List<T> {};

c570k3f3.collapse_all(zh-cn,VS.110).gif约束

约束是能用作类型参数的类型的限制。 例如,特定泛型类可接受来自指定的类继承仅的类,或实现了指定接口。 有关更多信息,请参见 泛型类型参数的约束 (C++/CLI)

引用类型和值类型

句柄类型和值类型只能用作类型参数。 在泛型定义,其中一个类型,可以使用语法是引用类型。 例如, -> 运算符用于该类型参数的类型的成员最终使用的类型是否为引用类型或值类型。 将值类型用作该类型参数时,运行时使用生成值类型直接,而无需对值类型进行装箱的代码。

在使用引用类型为泛型类型参数时,请使用处理语法。 在使用值类型作为泛型类型参数时,请直接使用类型的名称。

// generics_overview_2.cpp

// compile with: /clr

generic <typename T>

ref class GenericType {};

ref class ReferenceType {};

value struct ValueType {};

int main() {

GenericType<ReferenceType^> x;

GenericType<ValueType> y;

}

类型参数

在泛型类的类型参数象任何其他标识符。 但是,在中,因为类型未知,对其用法的限制。 例如,不能使用成员,并且类型参数的方法类别,除非该类型参数了解支持这些成员。 即访问一个成员将类型参数,必须将包含成员对类型参数的约束列表的类型。

// generics_overview_3.cpp

// compile with: /clr

interface class I {
   void f1();
   void f2();
};

ref struct R : public I {
   virtual void f1() {}
   virtual void f2() {} 
   virtual void f3() {} 
};

generic <typename T>
where T : I
void f(T t) {
   t->f1();
   t->f2();
   safe_cast<R^>(t)->f3();
}

int main() {
   f(gcnew R());
}

这些限制适用于运算符。 但是,如果该类型不支持这些运算符,一个不受约束的泛型类型参数不能使用 == 和 != 运算符比较类型参数的两个实例。 这些检查需要用于普通,但是,不适用于模板,因为泛型,可以专用在具有足够约束的任何类的运行时间,那么,当为时已晚检查使用无效成员时。

使用 () 运算符,类型参数的默认实例可以创建。 例如:

T t = T();

其中 T 是一个泛型类或泛型方法定义的类型参数,初始化变量为其默认值。 如果 T 是 ref 类将是 null 指针;如果 T 是值类,对象初始化为零。 这称为 默认初始值设定项。

请参见

其他资源

泛型(C++ 组件扩展)