首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C#中的IComparer<>和类继承

C#中的IComparer<>和类继承
EN

Stack Overflow用户
提问于 2011-07-07 14:24:56
回答 1查看 1.7K关注 0票数 2

有没有办法为基类类型实现专门的IComparer,以便子类仍然可以使用它来对特定的集合进行排序?

示例

代码语言:javascript
复制
public class A
{
   public int X;
}

public class B:A
{
   public int Y;
}

public AComparer:IComparer<A>
{
    int Compare(A p1, A p2)
    {
        //...
    }

}

所以下面的代码将会起作用:

代码语言:javascript
复制
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 

如何处理这个问题来同时继承排序和专门的集合(并且不为每个子类复制IComparer类?

提前感谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-07-07 14:32:03

首先,请注意,在.NET 4中,这是通过泛型逆变修复的-您的代码将简单地工作。编辑:正如注释中所指出的,泛型方差最初是在CLR v2中支持的,但在.NET 4中,各种接口和委托只成为协变或逆变。

然而,在.NET 2中创建转换器仍然相当容易:

代码语言:javascript
复制
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);
    }
}

然后,您可以使用:

代码语言:javascript
复制
List<B> bList = new List<B>();
IComparer<B> bComparer = new ComparerConverter<A, B>(new AComparer());
bList.Sort(bComparer);

编辑:如果不改变调用它的方式,你什么也做不了。不过,您可能会使AComparer成为泛型:

代码语言:javascript
复制
public class AComparer<T> : IComparer<T> where T : A
{
    int Compare(T p1, T p2)
    {
        // You can still access members of A here
    }    
}

然后你可以使用:

代码语言:javascript
复制
bList.Sort(new AComparer<B>());

当然,这意味着所有的比较器实现都是泛型的,这有点难看。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6606667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档