开发者

IComparer<> and class inheritance in C#

开发者 https://www.devze.com 2023-03-18 02:30 出处:网络
Is there any way to implement specialized IComparer for the base class type so a child class could still use it for sorting in speciliazed collections?

Is there any way to implement specialized IComparer for the base class type so a child class could still use it for sorting in speciliazed collections?

Example

public class A
{
   public int X;
}

public class B:A
{
   public int Y;
}

public AComparer:IComparer<A>
{
    int Compa开发者_如何学运维re(A p1, A p2)
    {
        //...
    }

}

so following code will work:

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 

How to approach this issue to have both - inheritance of sorting and specialized collections (and do not copy IComparer classes for each of children classes?

Thanks in advance!


Firstly, note that this is fixed in .NET 4 via generic contravariance - your code would simply work. EDIT: As noted in comments, generic variance was first supported in CLR v2, but various interfaces and delegates only became covariant or contravariant in .NET 4.

However, in .NET 2 it's still fairly easy to create a converter:

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);
    }
}

You can then use:

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

EDIT: There's nothing you can do without changing the way of calling it at all. You could potentially make your AComparer generic though:

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

Then you could use:

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

Of course, this means making all your comparer implementations generic, and it's somewhat ugly IMO.

0

精彩评论

暂无评论...
验证码 换一张
取 消