我目前正在阅读Jon skeet的精彩书籍#34; C#深度(3D版本)"。 我坚持第99页处理泛型缺乏逆转。
class TestGenericVariance
{
public static void Main(string[] args)
{
IComparer<IShape> x =new AreaComparer();
List<Circle> circles = new List<Circle>();
circles.Add(new Circle());
circles.Add(new Circle());
//The following line is invalid, Sort expects IComparer<Circle>
circles.Sort(x);
}
public interface IShape
{
}
public class Circle : IShape
{
}
public class AreaComparer : IComparer<IShape>
{
public int Compare(IShape x, IShape y)
{
//No matter, just for the test
return 0;
}
}
}
此代码无效,因为Sort方法需要
IComparer<Circle>
作为参数类型。
建议p.99的一个工作是使AreaComparer类通用:
class AreaComparer<T> : IComparer<T> where T : IShape
然后修改非泛型AreaComparer以从通用的那个派生:
class AreaComparer : AreaComparer<IShape>
在C#2中,代码没有编译,因为圆圈上的排序方法仍然需要
IComparer<Circle>
我错过了什么吗?
Nota:如果我改为:
class AreaComparer : AreaComparer<Circle>
main方法中的第一行代码要求形成显式转换
谢谢大家的帮助。
答案 0 :(得分:4)
我们的想法是让AreaComparer
像这样通用:
public class AreaComparer<T> : IComparer<T> where T : IShape
{
public int Compare(T x, T y)
{
return x.Area.CompareTo(y.Area);
}
}
然后,当您需要排序时,可以使用正确的类型参数构造比较器:
circles.Sort(new AreaComparer<Circle>());
请注意,这假设IShape
具有Area
属性(如p97底部所述)。这不是您的示例代码中所必需的,以便合理地实现比较器。
关于非泛型派生类的部分只是为了简化您对使用IShape
感到满意并且不想继续重复的情况。