Generic 类型参数和约束的规则
1. 泛型类可以从具体的、封闭式构造或开放式构造基类继承
class BaseNode { }
class BaseNodeGeneric<T> { }
// concrete type
class NodeConcrete<T> : BaseNode { }
//closed constructed type
class NodeClosed<T> : BaseNodeGeneric<int> { }
//open constructed type
class NodeOpen<T> : BaseNodeGeneric<T> { }
2. 非泛型类(换句话说,即具体类)可以从封闭式构造基类继承
l 无法从开放式构造类型,运行时客户端代码无法提供基类所需的参数类型
//No error
class Node1 : BaseNodeGeneric<int> { }
//Generates an error
//class Node2 : BaseNodeGeneric<T> {}
//Generates an error
//class Node3 : T {}
3. 从开放式构造类型继承的泛型类必须为任何未被继承类共享的基类类型参数提供类型变量
class BaseNodeMultiple<T, U> { }
//No error
class Node4<T> : BaseNodeMultiple<T, int> { }
//No error
class Node5<T, U> : BaseNodeMultiple<T, U> { }
//Generates an error
//class Node6<T> : BaseNodeMultiple<T, U> {}
4. 从开放式构造类型继承的泛型类必须指定约束,这些约束是基类型约束的超集或暗示基类型约束:
class NodeItem<T> where T : System.IComparable<T>, new() { }
class SpecialNodeItem<T> : NodeItem<T> where T : System.IComparable<T>, new() { }
5. 泛型类型可以使用多个类型参数和约束
class SuperKeyType<K, V, U>
where U : System.IComparable<U>
where V : new()
{ }
6. 开放式构造类型和封闭式构造类型可以用作方法参数
class myGenericA<T>
{
void Swap<T>(List<T> list1, List<T> list2)
{
//code to swap items
}
void Swap(List<int> list1, List<int> list2)
{
//code to swap items
}
}
7. 如果某个泛型类实现了接口,则可以将该类的所有实例强制转换为该接口
8. 泛型类是不变的
static void TestGenericBaseClass()
{
//Generate an error
List<object> myList = new List<string>();
//无法将类型“System.Collections.Generic.List<string>”隐式转换为“System.Collections.Generic.List<object>”
}