Я пытаюсь выяснить, какой из этих интерфейсов мне нужно реализовать. Они оба по существу делают одно и то же. Когда я буду использовать один над другим?
Когда использовать IComparable <T> Vs. IComparer <Т>
Ответ 1
Ну, это не то же самое, что IComparer<T>
реализуется в типе, который способен сравнивать два разных объекта, тогда как IComparable<T>
реализуется в типах, которые могут сравнивать себя с другими экземплярами того же типа.
Я обычно использую IComparable<T>
для тех случаев, когда мне нужно знать, как другой экземпляр относится к экземпляру this
. IComparer<T>
полезен для сортировки коллекций, поскольку IComparer<T>
стоит вне сравнения.
Ответ 2
Используйте IComparable<T>
, когда класс имеет внутреннее сравнение.
Используйте IComparer<T>
, если вам нужен метод сравнения, отличный от внутреннего сравнения класса, если он есть.
Ответ 3
Это зависит от объекта. Например, для класса, такого как "Student", имеет смысл иметь IComparable на основе Name.
class Student : IComparable
{
public string Name { get; set; }
public int MathScore { get; set; }
public int EnglishScore { get; set; }
public int TotalScore
{
get
{
return this.MathScore + this.EnglishScore;
}
}
public int CompareTo(object obj)
{
return CompareTo(obj as Student);
}
public int CompareTo(Student other)
{
if (other == null)
{
return 1;
}
return this.Name.CompareTo(other.Name);
}
}
Но если учитель "A" хочет сравнить студентов на основе MathScore, а учитель "B" хочет сравнить студентов на основе EnglishScore. Будет хорошей идеей реализовать IComparer отдельно. (Больше похоже на шаблон стратегии)
class CompareByMathScore : IComparer<Student>
{
public int Compare(Student x, Student y)
{
if (x.MathScore > y.MathScore)
return 1;
if (x.MathScore < y.MathScore)
return -1;
else
return 0;
}
}
Ответ 4
Все зависит от того, изменен ли ваш тип или нет. Вы должны только внедрять IComparable в непеременные типы. Обратите внимание: если вы реализуете IComparable, вы должны переопределить Equals вместе с ==,! =, < и > (см. Предупреждение анализа кода CA1036).
Цитата Dave G из это сообщение в блоге:
Но правильный ответ заключается в том, чтобы реализовать IComparer вместо IComparable, если ваши объекты изменяемы, и передать экземпляр IComparer для сортировки функций, когда это необходимо.
Поскольку IComparer - всего лишь одноразовый объект, используемый для сортировки в этот момент времени, ваш объект может иметь любую изменчивую семантику, которую вы желаете. Кроме того, он не требует или даже не предлагает использовать Equals, GetHashCode или == - вы можете определить его каким-либо образом.
Наконец, вы можете определить несколько IComparer для вашего типа для сортировки по разным полям или с разными правилами. Это гораздо более гибко, чем застревание с одним определением.
Короче: Используйте IComparable для типов значений и IComparer для ссылочных типов.
Ответ 5
Простое объяснение с помощью истории
баскетбол средней школы. это выбор школьного двора для команд. Я хочу получить самых высоких/лучших/быстрых людей в моей команде. Что мне делать?
Интерфейс Icomparer. Сравните двух людей с отдельными людьми.
- Это позволяет мне сравнивать любых двух парней, выстроенных в линию......... что в основном это. Фред против Джона.......... я бросаю их в конкретный класс, который реализует интерфейс.
Compare(Fred, John)
и он выплевывает, кто лучше.
Как насчет IComparable? - Сравните себя с кем-то другим
Вы недавно были в FB? Вы видите, что другие люди делают классные вещи: путешествуя по миру, создавая изобретения, в то время как вы застряли в переполнении переполнения базы мамаса, - ну, что вы делаете, это использование интерфейса IComparable.
- Вы сравниваете текущий экземпляр (самостоятельно) с другим объектом (кем-то другим), который имеет тот же тип (человек).
Как насчет класса Comparer?
Класс Comparer является абстрактным базовым классом, который реализует интерфейс Icomparer. Вы должны извлечь из этого класса конкретную реализацию. В любом случае Microsoft рекомендует использовать класс Comparer вместо реализации интерфейса Icomparer:
Мы рекомендуем, чтобы вы вышли из класса Comparer вместо реализации интерфейса IComparer, поскольку класс Comparer предоставляет явную реализацию интерфейса метода IComparer.Compare и свойство Default, которое получает сравнительный параметр по умолчанию для объекта.
Резюме
- IComparer - выровняйте две вещи и сравните.
- IComparable - сравните себя с другими на FB.
Надеюсь, что истории помогут вам запомнить.
Ответ 6
Как говорили другие, они не делают то же самое.
В любом случае, в настоящее время я, как правило, не использую IComparer. Почему я? Его ответственность (внешняя сущность, используемая для сравнения двух объектов) может быть обработана гораздо более чистым с помощью выражения лямбда, подобно тому, как работает большинство методов LINQ. Напишите быстрый лямбда, который берет объекты для сравнения в качестве аргументов и возвращает bool. И если объект определяет собственную операцию собственного сравнения, он может вместо этого реализовать IComparable.
Ответ 7
IComparable говорит, что объект можно сравнить с другим. IComparer - это объект, который может сравнивать любые два элемента.
Ответ 8
IComparer - это интерфейс, который используется для сортировки массива, этот интерфейс заставит класс реализовать Compare (T x, T y), который будет сравнивать два объекта. Экземпляр класса, который реализовал этот интерфейс, используется при сортировке массива.
IComparable - это интерфейс, реализованный в типе, который должен сравнивать два объекта одного и того же типа. Этот сопоставимый интерфейс заставит класс реализовать следующий метод CompareTo (T obj)
IEqualityComparer - это интерфейс, который используется для поиска объекта, независимо от того, является он равным или нет. Теперь мы увидим это в примере, где нам нужно найти отличительный элемент объекта в коллекции. Этот интерфейс реализует метод Равны (T obj1, T obj2)
Теперь мы возьмем пример, у нас есть класс Employee, основанный на этом классе, мы должны создать коллекцию. Теперь у нас есть следующие требования.
Сортировка массива с использованием класса Array 2. Нужна коллекция с использованием Linq: Удалите дубликат, порядок выше, чтобы опустить, Удалить идентификатор сотрудника
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
открытый класс EmployeeIdSorter: IComparer { public int Сравнить (Employee x, Employee y) { если (x.Id < y.Id) return 1; else if (x.Id > y.Id) return -1; еще return 0; } }
public class EmployeeSalarySorter : IComparer<Employee>
{
public int Compare(Employee x, Employee y)
{
if (x.Salary < y.Salary)
return 1;
else if (x.Salary > y.Salary)
return -1;
else
return 0;
}
}
Подробнее см. ниже http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html