IComparable
De en IComparer
interfaces gebruiken in Visual CSharp
In dit artikel wordt het gebruik van IComparer
en IComparable
interfaces in Visual C# beschreven.
Oorspronkelijke productversie: Visual C#
Oorspronkelijk KB-nummer: 320727
De IComparable
en IComparer
interfaces worden om twee redenen in hetzelfde artikel besproken. Deze interfaces worden vaak samen gebruikt. Hoewel de interfaces vergelijkbaar zijn en vergelijkbare namen hebben, dienen ze verschillende doeleinden.
Als u een matrix hebt van typen (zoals tekenreeks of geheel getal) die al worden ondersteund IComparer
, kunt u die matrix sorteren zonder expliciete verwijzing naar IComparer
. In dat geval worden de elementen van de matrix gecast naar de standaard implementatie van IComparer
(Comparer.Default
) voor u. Als u echter sorteer- of vergelijkingsmogelijkheden wilt bieden voor uw aangepaste objecten, moet u een of beide interfaces implementeren.
In dit artikel wordt verwezen naar de Naamruimte System.Collections
van de Microsoft .NET Framework-klassebibliotheek.
De rol van IComparable
is om een methode te bieden voor het vergelijken van twee objecten van een bepaald type. Het is nodig als u een bestelmogelijkheid voor uw object wilt bieden. IComparable
U kunt een standaardsorteervolgorde instellen voor uw objecten. Als u bijvoorbeeld een matrix met objecten van uw type hebt en u de Sort
methode voor die matrix aanroept, IComparable
geeft u de vergelijking van objecten tijdens het sorteren. Wanneer u de IComparable
interface implementeert, moet u de CompareTo
methode als volgt implementeren:
// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
Car c=(Car)obj;
return String.Compare(this.make,c.make);
}
De vergelijking in de methode verschilt, afhankelijk van het gegevenstype van de waarde die wordt vergeleken. String.Compare
wordt in dit voorbeeld gebruikt omdat de eigenschap die is gekozen voor de vergelijking een tekenreeks is.
De rol van IComparer
is om meer vergelijkingsmechanismen te bieden. U kunt bijvoorbeeld de volgorde van uw klasse opgeven voor verschillende velden of eigenschappen, oplopende en aflopende volgorde in hetzelfde veld, of beide.
Het gebruik IComparer
is een proces in twee stappen. Declareer eerst een klasse die implementeert IComparer
en implementeer vervolgens de Compare
methode:
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;
}
}
Notitie
Voor de IComparer.Compare
methode is een tertiaire vergelijking vereist. 1, 0 of -1 wordt geretourneerd, afhankelijk van of de ene waarde groter is dan, gelijk aan of kleiner is dan de andere. De sorteervolgorde (oplopend of aflopend) kan worden gewijzigd door de logische operatoren in deze methode te wijzigen.
De tweede stap is het declareren van een methode die een exemplaar van uw IComparer
object retourneert:
public static IComparer SortYearAscending()
{
return (IComparer) new SortYearAscendingHelper();
}
In dit voorbeeld wordt het object gebruikt als het tweede argument wanneer u de overbelaste Array.Sort
methode aanroept IComparer
die accepteert. Het gebruik van IComparer
is niet beperkt tot matrices. Het wordt geaccepteerd als een argument in veel verschillende verzamelings- en besturingsklassen.
In het volgende voorbeeld ziet u het gebruik van deze interfaces. Om te demonstreren IComparer
en IComparable
wordt er een klasse met de naam Car
gemaakt. Het Car
object heeft de eigenschappen make en year. Een oplopende sortering voor het veld Make wordt ingeschakeld via de IComparable
interface en een aflopende sortering op het veld Make wordt ingeschakeld via de IComparer
interface. Zowel oplopende als aflopende sorteringen worden geleverd voor de jaareigenschap met behulp van IComparer
.
Maak in Visual C# een nieuw consoletoepassingsproject. Noem de toepassing ConsoleEnum.
Wijzig de naam van Program.cs als Host.cs en vervang de code door de volgende code.
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(); } } }
Voeg een klasse toe aan het project. Geef de klasse auto een naam.
Vervang de code in Car.cs door de volgende code:
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(); } } }
Voer het project uit. De volgende uitvoer wordt weergegeven in het consolevenster :
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