C# BinarySearch повреждается при наследовании чему-то, что реализует IComparable <T>?

В.NET алгоритм BinarySearch (в Списках, Массивах, и т.д.), кажется, перестал работать, если объекты, которые Вы пытаетесь искать, наследовались IComparable вместо того, чтобы реализовать его непосредственно:

List<B> foo = new List<B>(); // B inherits from A, which implements IComparable<A>
foo.Add(new B());
foo.BinarySearch(new B());   // InvalidOperationException, "Failed to compare two elements in the array."

Где:

public abstract class A : IComparable<A>
{
    public int x;

    public int CompareTo(A other)
    {
        return x.CompareTo(other.x);
    }
}

public class B : A {}

Существует ли путь вокруг этого? Реализация CompareTo (B другой) в классе B, кажется, не работает.

5
задан Ender 2 May 2010 в 04:45
поделиться

2 ответа

В документации это довольно ясно сказано:

проверяет, реализует ли тип T универсальный интерфейс IComparable и использует ли эту реализацию, если она доступна. Если нет, Comparer.Default проверяет, реализует ли тип T интерфейс IComparable. Если тип T не реализует ни один интерфейс, Comparer.Default генерирует исключение InvalidOperationException.

Итак, простое решение - реализовать неуниверсальный интерфейс IComparable .
Добавление CompareTo (B other) будет работать для вас, если вы также реализуете IComparable - вы, вероятно, забыли этот бит .

Интересным решением является компиляция кода с использованием C # 4, где он выполняется без ошибок. C # 4 представляет Generic Covariance: открытый интерфейс IComparable <в T> vs открытый интерфейс IComparable , и опубликованный код работает, как ожидалось.

7
ответ дан 14 December 2019 в 04:32
поделиться

Верно, проблема в том, что он пытается проверить, реализует ли класс B IComparable , чего не делает, потому что он фактически реализует IComparable , затем пытается IComparable , после чего отказывается. Как указал Коби, реализация неуниверсального IComparable решит эту проблему.

1
ответ дан 14 December 2019 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: