要创建泛型类,只需要在类定义中包含尖括号语法:
class MyGenericClass<T> { ... }
其中T可以是任意标识符,只要遵循通常的C#命名规则即可,例如,不以数字开头等。但一般只使用T。泛型类可在其定义中包含任意多个类型参数,参数之间用逗号分隔,例如:
class MyGenericClass<Tl, T2, T3> { ... }
定义了这些类型后,就可以在类定义中像使用其他类型那样使用它们。可以把它们用作成员变量的类型、属性或方法等成员的返回类型以及方法的参数类型等。例如:
class MyGenericClass<Tl, T2, T3>
{
private T1 innerTlObject;
public MyGenericClass(T1 item)
{
innerTlObject = item;
}
public T1 InnerTlObject
{
get { return innerTlObjact; }
}
}
其中,类型T1的对象可以传递给构造函数,只能通过InnerTlObject属性对这个对象进行只读访问。注意,不能假定为类提供了什么类型。例如,下面的代码就不会编译:
class MyGenericClass<Tl, T2, T3>
{
private T1 innerTlObject;
public MyGenericClass()
{
innerTlObject = new T1 ();
}
public T1 InnerTlObject
{
get { return innerTlObject; }
}
}
我们不知道T1是什么,也就不能使用它的构造函数,它甚至可能没有构造函数,或者没有可公共访问的默认构造函数。如果不使用涉及高级技术的复杂代码,则只能对T1进行如下假设:可以把它看成继承自System.Object的类型或可以封箱到System.Object中的类型。
显然,这意味着不能对这个类型的实例进行非常有趣的操作,或者对为MyGenericClass泛型类提供的其他类型进行有趣的操作。不使用反射技术,就只能使用下面的代码:
public string GetAllTypesAsString()
{
return "T1 = " + typeof (Tl) .ToString() + T2 = " + typeof (T2) .ToString() + ", T3 = " + typeof (T3) .ToStringO ;
}
可以做一些其他工作,尤其是对集合进行操作,因为处理对象组是非常简单的,不需要对对象类型进行任何假设,这是为什么存在泛型集合类的一个原因。
另一个需要注意的限制是,在比较为泛型类型提供的类型值和null时,只能使用运算符=或!=。例如,下面的代码会正常工作:
public bool Compare{Tl opl, Tl op2)
{
if (opl != null && op2 != null)
{
return true;
}
else
{
return false;
}
}
其中,如果Tl是一个值类型,则总是假定它是非空的,于是在上面的代码中,Compare总是返回true。但是,下面试图比较两个实参opl和op2的代码将不能编译:
public bool Compare{Tl opl, Tl op2)
{
if (opl ~ op2)
{
return true;
}
else
{
return false;
}
}
其原因是这段代码假定Tl支持==运算符。这说明,要对泛型执行实际操作,需要更多地了解类中使用的类型。
已有 22658 名学员学习以下课程通过考试
最需教育客户端 软件问题一手掌握
去 App Store 免费下载 iOS 客户端
点击加载更多评论>>