正在阅读:C# 最强大的功能--泛型简介C# 最强大的功能--泛型简介

2005-06-23 10:16 出处: 作者:Juval Lowy 责任编辑:moningfeng

原因在于,编译器将拒绝编译以下行:

if(current.Key == key)



上述行将无法编译,因为编译器不知道 K(或客户端提供的实际类型)是否支持 == 运算符。例如,默认情况下,结构不提供这样的实现。您可以尝试通过使用 IComparable 接口来克服 == 运算符局限性:

public interface IComparable
{
int CompareTo(object obj);
}



如果您与之进行比较的对象等于实现该接口的对象,则 CompareTo() 返回 0;因此,Find() 方法可以按如下方式使用它:

if(current.Key.CompareTo(key) == 0)



遗憾的是,这也无法编译,因为编译器无法知道 K(或客户端提供的实际类型)是否派生自 IComparable。

您可以显式强制转换到 IComparable,以强迫编译器编译比较行,除非这样做需要牺牲类型安全:

if(((IComparable)(current.Key)).CompareTo(key) == 0)



如果客户端使用的类型不是派生自 IComparable,则会导致运行时异常。此外,当所使用的键类型是值类型而非键类型参数时,您可以对该键执行装箱,而这可能具有一些性能方面的影响。

派生约束

在 C# 2.0 中,可以使用 where 保留关键字来定义约束。在一般类型参数中使用 where 关键字,后面跟一个派生冒号,以指示编译器该一般类型参数实现了特定接口。例如,以下为实现 LinkedList 的 Find() 方法所必需的派生约束:

public class LinkedList where K : IComparable
{
T Find(K key)
{
Node current = m_Head;
while(current.NextNode != null)
{
if(current.Key.CompareTo(key) == 0)

break;
else

current = current.NextNode;
}
return current.Item;
}
//Rest of the implementation
}



您还将在您约束的接口的方法上获得 IntelliSense 支持。

当客户端声明一个 LinkedList 类型的变量,以便为列表的键提供类型实参时,客户端编译器将坚持要求键类型派生自 IComparable,否则,将拒绝生成客户端代码。

请注意,即使该约束允许您使用 IComparable,它也不会在所使用的键是值类型(例如,整型)时,消除装箱所带来的性能损失。为了克服该问题,System.Collections.Generic 命名空间定义了一般接口 IComparable:

public interface IComparable
{
int CompareTo(T other);
bool Equals(T other);
}


键盘也能翻页,试试“← →”键

关注我们

最新资讯离线随时看 聊天吐槽赢奖品