Uso de las IComparable
interfaces y IComparer
en Visual CSharp
En este artículo se describe el uso de IComparer
e IComparable
interfaces en Visual C#.
Versión original del producto: Visual C#
Número de KB original: 320727
Resumen
Las IComparable
interfaces y IComparer
se describen en el mismo artículo por dos motivos. Estas interfaces se usan con frecuencia juntas. Aunque las interfaces son similares y tienen nombres similares, sirven para diferentes propósitos.
Si tiene una matriz de tipos (como cadena o entero) que ya admiten IComparer
, puede ordenar esa matriz sin proporcionar ninguna referencia explícita a IComparer
. En ese caso, los elementos de la matriz se convierten en la implementación predeterminada de IComparer
(Comparer.Default
) automáticamente. Sin embargo, si desea proporcionar la funcionalidad de ordenación o comparación para los objetos personalizados, debe implementar cualquiera de estas interfaces o ambas.
En este artículo se hace referencia al espacio de nombres System.Collections
biblioteca de clases de Microsoft .NET Framework .
IComparable
El rol de IComparable
es proporcionar un método de comparación de dos objetos de un tipo determinado. Es necesario si desea proporcionar cualquier funcionalidad de ordenación para el objeto. Considere que proporciona un criterio de IComparable
ordenación predeterminado para los objetos. Por ejemplo, si tiene una matriz de objetos de su tipo y llama al Sort
método en esa matriz, IComparable
proporciona la comparación de objetos durante la ordenación. Al implementar la IComparable
interfaz, debe implementar el CompareTo
método , como se indica a continuación:
// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
Car c=(Car)obj;
return String.Compare(this.make,c.make);
}
La comparación en el método es diferente en función del tipo de datos del valor que se va a comparar. String.Compare
se usa en este ejemplo porque la propiedad elegida para la comparación es una cadena.
IComparer
El rol de es proporcionar más mecanismos de IComparer
comparación. Por ejemplo, es posible que desee proporcionar el orden de la clase en varios campos o propiedades, orden ascendente y descendente en el mismo campo, o ambos.
El uso IComparer
es un proceso de dos pasos. En primer lugar, declare una clase que implemente IComparer
y, a continuación, implemente el Compare
método :
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;
}
}
Nota:
El IComparer.Compare
método requiere una comparación terciaria. 1, 0 o -1 se devuelve en función de si un valor es mayor, igual o menor que el otro. El criterio de ordenación (ascendente o descendente) se puede cambiar cambiando los operadores lógicos de este método.
El segundo paso consiste en declarar un método que devuelve una instancia del IComparer
objeto :
public static IComparer SortYearAscending()
{
return (IComparer) new SortYearAscendingHelper();
}
En este ejemplo, el objeto se usa como segundo argumento cuando se llama al método sobrecargado Array.Sort
que acepta IComparer
. El uso de IComparer
no se limita a las matrices. Se acepta como un argumento en muchas clases de control y colección diferentes.
Ejemplo paso a paso
En el ejemplo siguiente se muestra el uso de estas interfaces. Para mostrar IComparer
y IComparable
, se crea una clase denominada Car
. El Car
objeto tiene las propiedades make y year. Una ordenación ascendente para el campo make se habilita a través de la IComparable
interfaz y una ordenación descendente en el campo make se habilita a través de la IComparer
interfaz. Las ordenaciones ascendentes y descendentes se proporcionan para la propiedad year mediante IComparer
.
En Visual C#, cree un nuevo proyecto de aplicación de consola. Asigne a la aplicación el nombre ConsoleEnum.
Cambie el nombre de Program.cs como Host.cs y, a continuación, reemplace el código por el código siguiente.
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(); } } }
Agregue una clase al proyecto. Asigne un nombre a la clase Car.
Reemplace el código de Car.cs por el código siguiente:
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(); } } }
Ejecute el proyecto. La siguiente salida aparece en la ventana Consola :
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
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de