C# 中的 IComparer<> 和类继承



是否有任何方法实现基类类型的专门化ic比较器,以便子类仍然可以使用它在专门化集合中进行排序?

例子
public class A
{
   public int X;
}
public class B:A
{
   public int Y;
}
public AComparer:IComparer<A>
{
    int Compare(A p1, A p2)
    {
        //...
    }
}

所以下面的代码可以工作:

List<A> aList = new List<A>();
aList.Sort(new AComparer());
List<B> bList = new List<B>();
bList.Sort(new AComparer()); // <- this line fails due to type cast issues 

如何处理这个问题,有排序和专门化集合的继承(和不复制iccomparer类的每一个子类?

提前感谢!

首先,注意这在。net 4中是通过泛型逆变修复的——你的代码就可以正常工作了。编辑:正如在注释中提到的,泛型方差最初是在CLR v2中支持的,但是各种接口和委托直到。net 4才变成协变或逆变。

然而,在。net 2中创建一个转换器仍然相当容易:

public class ComparerConverter<TBase, TChild> : IComparer<TChild>
    where TChild : TBase
{
    private readonly IComparer<TBase> comparer;
    public ComparerConverter(IComparer<TBase> comparer)
    {
        this.comparer = comparer;
    }
    public int Compare(TChild x, TChild y)
    {
        return comparer.Compare(x, y);
    }
}

你可以使用:

List<B> bList = new List<B>();
IComparer<B> bComparer = new ComparerConverter<A, B>(new AComparer());
bList.Sort(bComparer);

编辑:如果不改变调用的方式,你就什么也做不了。您可能会使您的AComparer通用:

public class AComparer<T> : IComparer<T> where T : A
{
    int Compare(T p1, T p2)
    {
        // You can still access members of A here
    }    
}

那么你可以使用:

bList.Sort(new AComparer<B>());

当然,这意味着让你所有的比较器实现通用,在我看来,这有点难看。

最新更新