更新:2007 年 11 月
将泛型类型或方法编译为 Microsoft 中间语言 (MSIL) 时,它包含将其标识为具有类型参数的元数据。泛型类型的 MSIL 的使用因所提供的类型参数是值类型还是引用类型而不同。
第一次用值类型作为参数来构造泛型类型时,运行时会创建专用泛型类型,将提供的参数代入到 MSIL 中的适当位置。对于每个用作参数的唯一值类型,都会创建一次专用泛型类型。
例如,假设您的程序代码声明了一个由整数构造的堆栈:
C# | 复制代码 |
---|---|
Stack<int> stack;
|
在此位置,运行时生成
C# | 复制代码 |
---|---|
Stack<int> stackOne = new Stack<int>(); Stack<int> stackTwo = new Stack<int>(); |
但是,假定在代码中的另一个位置创建了使用不同值类型(比如 long 或用户定义的结构)作为其参数的另一个
对于引用类型,泛型的工作方式略有不同。第一次使用任何引用类型构造泛型类型时,运行时会创建专用泛型类型,用对象引用替换 MSIL 中的参数。然后,每次使用引用类型作为参数来实例化构造类型时,无论引用类型的具体类型是什么,运行时都会重用以前创建的泛型类型的专用版本。之所以可以这样,是因为所有引用的大小相同。
例如,假设您有两个引用类型:一个 Customer 类和一个 Order 类,并且同时假设您创建了一个 Customer 类型的堆栈:
C# | 复制代码 |
---|---|
class Customer { } class Order { } |
C# | 复制代码 |
---|---|
Stack<Customer> customers; |
此时,运行时将生成
C# | 复制代码 |
---|---|
Stack<Order> orders = new Stack<Order>();
|
不同于值类型,对于 Order 类型不创建
C# | 复制代码 |
---|---|
customers = new Stack<Customer>();
|
与前面使用 Order 类型创建的
此外,使用值类型或引用类型参数实例化泛型 C# 类时,反射可以在运行时查询它,并且可以确定它的实际类型及其类型参数。