#c_sharp
Для чего нужен интерфейс icomparable? Я новичок и прошу объяснить на пальцах зачем
он нужен и что он делает?
Ответы
Ответ 1
tl;dr: Интерфейс IComparable нужен потому, что иначе нельзя использовать сравнение в функциях, которые работают с произвольным типом данных. Смотрите. Для того, чтобы упорядочить объекты, их нужно сравнивать. Если тип объектов известен заранее, то для сравнения проще всего использовать операторы >/=. Теперь вопрос, а как же сравнивать объекты, если тип их неизвестен? Например, если у нас есть набор элементов произвольного типа (например, generic-типа T)? Для того, чтобы выразить идею «объект X что-то умеет», в .NET используются интерфейсы. Но в интерфейсе нельзя выразить «объект умеет сравниваться с другим». Поэтому и был придуман интерфейс IComparable (а также его более современный собрат IComparable), который описывает операцию сравнения. Пример: пускай вы хотите написать функцию Max, которая находит максимальный элемент из списка. Простой пример — Max для чисел типа int. Как мы помним, для конкретных типов интерфейс не так уж и нужен. Пишем реализацию: int Max(IEnumerable list) { int max = 0; bool first = true; foreach (var x in list) { if (first) { first = false; max = x; } else { if (x > max) max = x; } } if (first) throw new ArgumentException("список пустой!"); return max; } Это было несложно. Теперь попробуем обобщить этот метод на произвольный тип T. Попробуем обобщить предыдущий метод: T Max<Т>(IEnumerable list) { T max = default(T); bool first = true; foreach (var x in list) { if (first) { first = false; max = x; } else { if (x > max) max = x; } } if (first) throw new ArgumentException("список пустой!"); return max; } Получаем ошибку: error CS0019: Operator '>' cannot be applied to operands of type 'T' and 'T'. Потому что компилятор не знает, как ему сравнивать произвольный тип T (и можно ли вообще). Вспоминаем про интерфейс IComparable , и пользуемся им. Во-первых, мы потребуем, чтобы объекты типа T можно было сравнивать с другими объектами того же типа: T Max (IEnumerable list) where T : IComparable Далее, вместо сравнения через > применяем сравнение через IComparable : if (x.CompareTo(max) > 0) max = x; Пробуем: int[] list = { 1, 7, 2, 99, -14 }; Console.WriteLine(Max(list)); — получаем на выходе 99. Заметьте, что если вы определите operator > и operator ==, то этим самым автоматически не будет поддерживаться интерфейс IComparable . Вы должны будете определить его вручную. Можно считать это недостатком в текущей реализации языка. Дополнительное чтение по теме: Eric Lippert: Double Your Dispatch, Double Your Fun.
Комментариев нет:
Отправить комментарий