C#2中泛型的限制

时间:2016-07-05 15:40:16

标签: c# generics

我目前正在阅读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方法中的第一行代码要求形成显式转换

谢谢大家的帮助。

1 个答案:

答案 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感到满意并且不想继续重复的情况。