接泛型二
这篇文章是翻译的微软的技术文章.供学习c#的朋友参考,请勿用于商业目的。http://msdn.microsoft.com/vcsharp/team/language/default.aspx
20.4 泛型委托声明
委托声明可以包含类型参数。
delegate-declaration:
attributes opt delegate-modifiers op t delegate return-type identifier type-parameter-list opt
(formal-parameter-list opt) type-parameter-constraints-clauses opt;
(委托声明: 特性可选 委托修饰符可选 delegate 返回类型 标识符 类型参数列表可选 (正式参数列表可选 )类型参数约束语句可选
使用类型参数声明的委托是一个泛型委托声明。委托声明只有在支持类型参数列表时,才能支持类型参数约束语句(§20.7)。除了所指出的之外,泛型委托声明和常规的委托声明遵循相同的规则。泛型委托声明中的每个类型参数,在与委托关联的特定声明空间(§3.3)定义了一个名字。在委托声明中的类型参数的作用域包括返回类型、正式参数列表和类型参数约束语句。
像其他泛型类型声明一样,必须给定类型实参以形成构造委托类型。构造委托类型的参数和返回值,由委托声明中构造委托类型的每个类型参数对应的实参替代所形成。而结果返回类型和参数类型用于确定什么方法与构造委托类型兼容。例如
delegate bool Predicate<T>(T value)
class X
{
static bool F(int i){…}
static bool G(string s){…}
static void Main(){
Predicate<int> p1 = F;
Predicate<string> p2=G;
}
}
注意在先前的Main方法中的两个赋值等价于下面的较长形式.
static void Main(){
Predicate<int> p1 = new Predicate<int>(F);
Predicate<string> p2 = new Predicate<string>(G);
}
由于方法组转换,较短的形式也是可以的,这在§21.9中有说明。
20.5构造类型
泛型类型声明自身并不表示一个类型。相反,泛型类型声明通过应用类型实参的方式被用作形成许多不同类型的“蓝图”。类型参数被写在尖括号之间,并紧随泛型类型声明名字之后。使用至少一个实参而被命名的类型被称为构造类型(constructed type)。构造类型可以用在语言中类型名字可以出现的大多数地方。
type-name:(类型名字:)
namespace-or-type-name(命名空间或类型名字)
namespace-or-type-name:(命名空间或类型名字:)
identifier type-argument-list(标识符类型实参列表可选)
namespace-or-type-name. identifier(命名空间或类型名字.标识符)
type-argument-list opt(类型实参列表可选)
构造类型也能被用在表达式中作为简单名字(§20.9.3)或者访问一个成员(§20.9.4)。
当一个命名空间或类型名字被计算时,只有带有正确数量类型参数的泛型类型会被考虑。由此,只要类型有不同数量的类型参数并且声明在不同的命名空间,那么使用相同的标识符标识不同的类型是可能的。这对于在同一程序中混合使用泛型和非泛型类是很有用的。
namespace System.Collections
{
class Queue{…}
}
namespace Sysetm.Collections.Generic
{
class Queue<ElementType>{…}
}
namespace MyApplication
{
using System.Collections;
using System.Collections.Generic;
class X
{
Queue q1; //System.Collections.Queue
Queue<int> q2;//System.Collections.Generic.Queue
}
}
在这些代码中对于名字查找的详细规则在§20.9中进行了描述。在这些代码中对于模糊性的决议在§20.6.5中进行了描述。
类型名字可能标识一个构造类型,尽管它没有直接指定类型参数。这种情况在一个类型嵌套在一个泛型类声明中时就会出现,并且包含声明的实例类型将因为名字查找(§20.1.2)而被隐式地使用。
class Outer<T>
{
public class Inner{…}
public Inner i; //i的类型是Outer<T>.Inner
}
在不安全代码中,构造类型不能被用作非托管类型(§18.2)。
20.5.1类型实参
在一个类型参数列表中的每个实参都只是一个类型。
type-argument-list:(类型实参列表:)
<type-arguments>(<类型实参>)
type-arguments:(类型实参:)
type-argument(类型实参)
type-arguments, type-argument(类型实参,类型实参)
type-argument:(类型实参:)
type(类型)
类型实参反过来也可以是构造类型或类型参数。在不安全代码中(§18),类型实参不能是指针类型。每个类型实参必须遵循对应类型参数(§20.7.1)上的任何约束。
20.5.2开放和封闭类型
所有类型都可以被分为开放类型(open type)或封闭类型(closed type)。开放类型是包含类型参数的类型。更明确的说法是
类型参数定义了一个开放类型
数组类型只有当其元素是一个开放类型时才是开放类型
构造类型只有当其类型实参中的一个或多个是开放类型时,它才是开放类型
非开放类型都是封闭类型。
在运行时,在泛型类型声明中的所有代码都在一个封闭构造类型的上下文执行,这个封闭构造类型是通过将类型实参应用到泛型声明中创建的。在泛型类型中的每个类型实参被绑定到一个特定运行时类型。所有语句和表达式的运行时处理总是针对封闭类型发生,而开放类型只发生在编译时处理。
每个封闭构造类型都有它自己的一组静态变量,它们并不被其他封闭类型共享。因为在运行时不存在开放类型,所以开放类型没有关联的静态变量。如果两个封闭构造类型是从同一个类型声明构造的,并且对应的类型实参也是相同的类型,那么它们就是相同的类型。
20.5.3构造类型的基类和接口
构造类类型有一个直接基类,就像是一个简单类类型。如果泛型类声明没有指定基类,其基类为object。如果基类在泛型类声明中被指定,构造类型的基类通过将在基类声明中的每个类型参数,替代为构造类型对应类型实参而得到。给定泛型类声明
cla