泛型概述
一,泛型和强制类型转换
•C# 编译器只允许将泛型参数隐式强制转换到Object 或约束指定的类型
• 编译器允许您将泛型参数显式强制转换到其他任何接口,但不能将其转换到类
• 但是,您可以使用临时的Object 变量,将泛型参数强制转换到其他任何类型 (可以通过编译,但是运行时会异常)
class SomeClass
{
}
class MyClass<T>
{
void SomeMethod(T t)
{
//可以先转换成 Object,再转换成类。
object temp = t;
SomeClass obj = (SomeClass)temp;
}
}
{
}class MyClass<T>
{
void SomeMethod(T t)
{
//可以先转换成 Object,再转换成类。
object temp = t;
SomeClass obj = (SomeClass)temp;
}
}
二,继承和泛型
• 在从泛型基类派生时,可以提供类型实参,而不是基类泛型参数
public class BaseClass<T>
{
}
public class SubClass : BaseClass<int>
{
}
{
}public class SubClass : BaseClass<int>
{
}• 如果子类是泛型,而非具体的类型实参,则可以使用子类泛型参数作为泛型基类的指定类型
public class BaseClass<T>
{
}
public class SubClass<T> : BaseClass<T>
{
}
{
}public class SubClass<T> : BaseClass<T>
{
}• 在使用子类泛型参数时,必须在子类级别重复在基类级别规定的任何约束
public class BaseClass<T> where T : ISomeInterface
{
}
public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{
}
{
}public class SubClass<T> : BaseClass<T> where T : ISomeInterface
{
}• 基类可以定义其签名使用泛型参数的虚拟方法。在重写它们时,子类必须在方法签名中提供相应的类型
public class BaseClass<T>
{
public virtual T SomeMethod()
{
}
}
public class SubClass: BaseClass<int>
{
public override int SomeMethod()
{
}
}
{
public virtual T SomeMethod()
{
}}
public class SubClass: BaseClass<int>
{
public override int SomeMethod()
{
}}
• 如果该子类是泛型类,则它还可以在重写时使用它自己的泛型参数
public class SubClass<T>: BaseClass<T>
{
public override T SomeMethod()
{
}
}
{
public override T SomeMethod()
{
}}
三,泛型方法
• 在C# 2.0 中,方法可以定义特定于其执行范围的泛型参数
public class MyClass<T>
{
public void MyMethod<X>(X x)
{
}
}
• 注意:该功能仅适用于方法。属性或索引器只能使用在类的作用范围中定义的泛型参数。{
public void MyMethod<X>(X x)
{
}}
• 因此,当调用该方法时,C# 编译器将足够聪明,从而基于传入的参数的类型推断出正确的类型,并且它允许完全省略类型规范
泛型推理
MyClass obj = new MyClass();
obj.MyMethod<int>(3);
MyClass obj = new MyClass();
obj.MyMethod(3);
obj.MyMethod<int>(3);
MyClass obj = new MyClass();
obj.MyMethod(3);
四,泛型和反射
• 在.NET 2.0 中,扩展了反射以支持泛型参数。类型Type现在可以表示带有特定类型实参(称为绑定类型)或未指定
(未绑定)类型的泛型。像C# 1.1 中一样,您可以通过使用typeof 运算符或者通过调用每个类型支持的GetType()
方法来获得任何类型的Type
LinkedList<int,string> list = new LinkedList<int,string>();
Type type1 = typeof(LinkedList<int,string>);
Type type2 = list.GetType();
Debug.Assert(type1 == type2);
Type type1 = typeof(LinkedList<int,string>);
Type type2 = list.GetType();
Debug.Assert(type1 == type2);
• typeof 和GetType() 都可以对泛型参数进行操作
public class MyClass<T>
{
public void SomeMethod(T t)
{
Type type = typeof(T);
Debug.Assert(type == t.GetType());
}
}
{
public void SomeMethod(T t)
{
Type type = typeof(T);
Debug.Assert(type == t.GetType());
}
}
• 请注意空<> 的用法。要对带有多个类型参数的未绑定泛型类型进行操作,请在<> 中使用“,”
public class LinkedList<K,T>
{
}
Type unboundedList = typeof(LinkedList<,>);
Trace.WriteLine(unboundedList.ToString());
//Writes: LinkedList`2[K,T]
Code
{
}Type unboundedList = typeof(LinkedList<,>);
Trace.WriteLine(unboundedList.ToString());
//Writes: LinkedList`2[K,T]
• 与Type 类似,MethodInfo 和它的基类MethodBase 具有反射泛型方法信息的新成员

五,泛型无法完成的工作
• 在.NET 2.0 下,您不能定义泛型Web 服务,即使用泛型
类型参数的Web 方法。原因是没有哪个Web 服务标准支
持泛型服务。
• 您还不能在服务组件上使用泛型类型。原因是泛型不能满
足COM 可见性要求,而该要求对于服务组件而言是必需
的(就像您无法在COM 或COM+ 中使用C++ 模板一样)

浙公网安备 33010602011771号