Este artigo passo a passo descreve a utilização de duas interfaces:
IComparer e
IComparable . Estas interfaces são abordadas no artigo mesmo por dois motivos. Estas interfaces são frequentemente utilizadas em conjunto e apesar das interfaces são semelhantes (e têm nomes semelhantes), podem servem finalidades diferentes.
Se tiver uma matriz de tipos (tais como
cadeia ou
número inteiro ) que já suportam
IComparer , é possível ordenar dessa matriz sem fornecer quaisquer referências explícitas a
IComparer . Nesse caso, os elementos da matriz são convertidos para a implementação de predefinição de
IComparer (
Comparer.Default ) para. No entanto, se pretender fornecer capacidade de ordenação ou comparação para os objectos personalizados, tem de implementar uma ou ambas estas interfaces.
Espaço de nomes seguinte biblioteca de classes do .NET Framework é referenciado neste artigo:
System.Collections
IComparable
A função de
IComparable é fornecer um método de comparar dois objectos de um determinado tipo. Isto é necessário se pretender fornecer qualquer encomenda capacidade para o objecto. Pense
IComparable como fornecer uma sequência de ordenação predefinida para os objectos. Por exemplo, se tiver uma matriz de objectos do tipo, chamar o método
ordenação dessa matriz
IComparable fornece a comparação de objectos durante a ordenação. Quando implementar a interface
IComparable , tem de implementar o método
CompareTo , da seguinte forma:
// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
car c=(car)obj;
return String.Compare(this.make,c.make);
}
é diferente dependendo do tipo de dados do valor que está a ser comparado a comparação no método.
String.Compare é utilizado neste exemplo, porque a propriedade é escolhida para a comparação é uma cadeia.
IComparer
A função de
IComparer é fornecer mecanismos de comparação adicionais. Por exemplo, poderá fornecer a ordenação da classe em vários campos ou propriedades, ascendente e descendente o mesmo campo, ou ambas.
Utilizar
IComparer é um processo composto por dois passos. Em primeiro lugar, declarar uma classe que implementa
IComparer e, em seguida, implementar o método
Comparar :
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 que o método
IComparer.Compare requer um terciário comparação. 1, 0 ou -1 é devolvida dependendo se um valor é superior, igual ou menor que o outro. A sequência de ordenação (ascendente ou descendente) pode ser alterada mudando os operadores lógicos neste método.
O segundo passo consiste em declarar um método que devolve uma ocorrência do objecto de
IComparer :
public static IComparer sortYearAscending()
{
return (IComparer) new sortYearAscendingHelper();
}
neste exemplo, o objecto é utilizado como o segundo argumento quando chamar o método de
Array.Sort sobrecarregado que aceita
IComparer . A utilização de
IComparer não está limitada para matrizes. É aceite como um argumento num número de colecção diferente e classes de controlo.
Exemplo passo a passo
O exemplo seguinte demonstra a utilização destas interfaces. Para demonstrar
IComparer e
IComparable , é criada uma classe denominada
carro . O objecto de
carro tem as propriedades de
fazer e o
ano . Ordenação ascendente para
tornar campo está activado através de interface
IComparable e descendente em
que campo está activado através da interface
IComparer . O ascendente e descendente Ordena são fornecidos para a propriedade
ano através da utilização de
IComparer .
- No Visual C#, crie um novo projecto de aplicação de consola. Nome da aplicação ConsoleEnum.
- Mude o nome Program.cs como Host.cs e, em seguida, substitua o código com o seguinte código.
Nota No Visual Studio .NET 2003, mudar o nome Class1.cs como Host.cs.
using System;
namespace ConsoleEnum
{
class host
{
[STAThread]
static void Main(string[] args)
{
// Create an arary 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();
}
}
}
- Adicione uma classe ao projecto. Nome da classe carro .
- Substitua o código de Car.cs com o seguinte:
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();
}
}
}
- Execute o projecto. O seguinte resultado aparece na janela da 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