Во-первых, обратите внимание, что это исправлено в .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>());
Конечно, это означает, что все ваши реализации компаратора будут универсальными, и это несколько уродливоИМО.