IComparable
Использование интерфейсов и IComparer
в Visual CSharp
В этой статье описывается использование интерфейсов IComparer
и IComparable
в Visual C#.
Исходная версия продукта: Visual C#
Исходный номер базы знаний: 320727
Сводка
Интерфейсы IComparable
и IComparer
рассматриваются в одной статье по двум причинам. Эти интерфейсы часто используются вместе. Хотя интерфейсы похожи и имеют похожие имена, они служат для разных целей.
Если у вас есть массив типов (например, string или integer), которые уже поддерживают IComparer
, вы можете сортировать этот массив, не указывая явных ссылок на IComparer
. В этом случае элементы массива будут приведены к реализации IComparer
по умолчанию (Comparer.Default
). Однако если вы хотите предоставить возможность сортировки или сравнения для пользовательских объектов, необходимо реализовать один из этих интерфейсов или оба этих интерфейса.
В этой статье содержится ссылка на пространство System.Collections
имен библиотеки классов Microsoft платформа .NET Framework .
IComparable
Роль IComparable
заключается в предоставлении метода сравнения двух объектов определенного типа. Это необходимо, если вы хотите предоставить возможность упорядочивания для объекта. Подумайте о том, как предоставить порядок сортировки IComparable
по умолчанию для объектов. Например, если у вас есть массив объектов вашего типа и вы вызываете Sort
метод в этом массиве, IComparable
выполняется сравнение объектов во время сортировки. При реализации IComparable
интерфейса необходимо реализовать CompareTo
метод следующим образом:
// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
Car c=(Car)obj;
return String.Compare(this.make,c.make);
}
Сравнение в методе отличается в зависимости от типа данных сравниваемого значения. String.Compare
используется в этом примере, так как свойство, выбранное для сравнения, является строкой.
IComparer
Роль заключается в предоставлении дополнительных IComparer
механизмов сравнения. Например, может потребоваться упорядочение класса по нескольким полям или свойствам, по возрастанию и убыванию одного и того же поля или по обоим полям.
Использование IComparer
— это двухэтапный процесс. Сначала объявите класс, реализующий IComparer
, а затем реализуйте Compare
метод :
private class SortYearAscendingHelper : IComparer
{
int IComparer.Compare(object a, object b)
{
Car c1=(Car)a;
Car c2=(Car)b;
if (c1.year > c2.year)
return 1;
if (c1.year < c2.year)
return -1;
else
return 0;
}
}
Примечание.
Для IComparer.Compare
метода требуется третичное сравнение. Значение 1, 0 или -1 возвращается в зависимости от того, больше ли одно значение, равно или меньше другого. Порядок сортировки (по возрастанию или убыванию) можно изменить путем переключения логических операторов в этом методе.
Второй шаг заключается в объявлении метода, который возвращает экземпляр объекта IComparer
:
public static IComparer SortYearAscending()
{
return (IComparer) new SortYearAscendingHelper();
}
В этом примере объект используется в качестве второго аргумента при вызове перегруженного Array.Sort
метода, который принимает IComparer
. Использование IComparer
не ограничивается массивами. Он принимается в качестве аргумента во многих различных классах коллекций и элементов управления.
Пошаговый пример
В следующем примере показано использование этих интерфейсов. Для демонстрации IComparer
и IComparable
создается класс с именем Car
. Объект Car
имеет свойства make и year. Сортировка по возрастанию для поля make включается через IComparable
интерфейс, а сортировка по убыванию в поле make включается через IComparer
интерфейс . Сортировка по возрастанию и убыванию предоставляется для свойства year с помощью IComparer
.
В Visual C# создайте проект консольного приложения. Присвойтите приложению имя ConsoleEnum.
Переименуйте Program.cs как Host.cs, а затем замените код следующим кодом.
using System; namespace ConsoleEnum { class host { [STAThread] static void Main(string[] args) { // Create an array of Car objects. Car[] arrayOfCars= new Car[6] { new Car("Ford",1992), new Car("Fiat",1988), new Car("Buick",1932), new Car("Ford",1932), new Car("Dodge",1999), new Car("Honda",1977) }; // Write out a header for the output. Console.WriteLine("Array - Unsorted\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo IComparable by sorting array with "default" sort order. Array.Sort(arrayOfCars); Console.WriteLine("\nArray - Sorted by Make (Ascending - IComparable)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo ascending sort of numeric value with IComparer. Array.Sort(arrayOfCars,Car.SortYearAscending()); Console.WriteLine("\nArray - Sorted by Year (Ascending - IComparer)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo descending sort of string value with IComparer. Array.Sort(arrayOfCars,Car.SortMakeDescending()); Console.WriteLine("\nArray - Sorted by Make (Descending - IComparer)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); // Demo descending sort of numeric value using IComparer. Array.Sort(arrayOfCars,Car.SortYearDescending()); Console.WriteLine("\nArray - Sorted by Year (Descending - IComparer)\n"); foreach(Car c in arrayOfCars) Console.WriteLine(c.Make + "\t\t" + c.Year); Console.ReadLine(); } } }
Добавьте класс в проект. Назовите класс Car.
Замените код в Car.cs следующим кодом:
using System; using System.Collections; namespace ConsoleEnum { public class Car : IComparable { // Beginning of nested classes. // Nested class to do ascending sort on year property. private class SortYearAscendingHelper: IComparer { int IComparer.Compare(object a, object b) { Car c1=(Car)a; Car c2=(Car)b; if (c1.year > c2.year) return 1; if (c1.year < c2.year) return -1; else return 0; } } // Nested class to do descending sort on year property. private class SortYearDescendingHelper: IComparer { int IComparer.Compare(object a, object b) { Car c1=(Car)a; Car c2=(Car)b; if (c1.year < c2.year) return 1; if (c1.year > c2.year) return -1; else return 0; } } // Nested class to do descending sort on make property. private class SortMakeDescendingHelper: IComparer { int IComparer.Compare(object a, object b) { Car c1=(Car)a; Car c2=(Car)b; return String.Compare(c2.make,c1.make); } } // End of nested classes. private int year; private string make; public Car(string Make,int Year) { make=Make; year=Year; } public int Year { get {return year;} set {year=value;} } public string Make { get {return make;} set {make=value;} } // Implement IComparable CompareTo to provide default sort order. int IComparable.CompareTo(object obj) { Car c=(Car)obj; return String.Compare(this.make,c.make); } // Method to return IComparer object for sort helper. public static IComparer SortYearAscending() { return (IComparer) new SortYearAscendingHelper(); } // Method to return IComparer object for sort helper. public static IComparer SortYearDescending() { return (IComparer) new SortYearDescendingHelper(); } // Method to return IComparer object for sort helper. public static IComparer SortMakeDescending() { return (IComparer) new SortMakeDescendingHelper(); } } }
Запустите проект. В окне консоли отображаются следующие выходные данные:
Array - Unsorted Ford 1992 Fiat 1988 Buick 1932 Ford 1932 Dodge 1999 Honda 1977 Array - Sorted by Make (Ascending - IComparable) Buick 1932 Dodge 1999 Fiat 1988 Ford 1932 Ford 1992 Honda 1977 Array - Sorted by Year (Ascending - IComparer) Ford 1932 Buick 1932 Honda 1977 Fiat 1988 Ford 1992 Dodge 1999 Array - Sorted by Make (Descending - IComparer) Honda 1977 Ford 1932 Ford 1992 Fiat 1988 Dodge 1999 Buick 1932 Array - Sorted by Year (Descending - IComparer) Dodge 1999 Ford 1992 Fiat 1988 Honda 1977 Buick 1932 Ford 1932
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по