Visual CSharp で
この記事では、Visual C# での IComparer
インターフェイスと IComparable
インターフェイスの使用方法について説明します。
元の製品バージョン: Visual C#
元の KB 番号: 320727
まとめ
IComparable
インターフェイスとIComparer
インターフェイスについては、2 つの理由から同じ記事で説明します。 これらのインターフェイスは、一緒に頻繁に使用されます。 インターフェイスは似ていますが、名前は似ていますが、さまざまな目的に対応します。
既に IComparer
をサポートしている型 (文字列や整数など) の配列がある場合は、 IComparer
への明示的な参照を指定せずに、その配列を並べ替えることができます。 その場合、配列の要素は、 IComparer
(Comparer.Default
) の既定の実装にキャストされます。 ただし、カスタム オブジェクトの並べ替えまたは比較機能を提供する場合は、これらのインターフェイスのいずれかまたは両方を実装する必要があります。
この記事では、Microsoft .NET Framework クラス ライブラリ名前空間 System.Collections
を参照します。
IComparable
IComparable
の役割は、特定の型の 2 つのオブジェクトを比較する方法を提供することです。 オブジェクトに任意の順序付け機能を提供する場合に必要です。 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
の使用は 2 段階のプロセスです。 まず、 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;
}
}
Note
IComparer.Compare
メソッドには、3 番目の比較が必要です。 1、 0、または -1 は、一方の値が他方より大きいか、等しいか、またはそれより小さいかに応じて返されます。 並べ替え順序 (昇順または降順) は、このメソッドの論理演算子を切り替えることで変更できます。
2 番目の手順では、 IComparer
オブジェクトのインスタンスを返すメソッドを宣言します。
public static IComparer SortYearAscending()
{
return (IComparer) new SortYearAscendingHelper();
}
この例では、IComparer
を受け入れるオーバーロードされたArray.Sort
メソッドを呼び出すときに、オブジェクトが 2 番目の引数として使用されます。 IComparer
の使用は配列に限定されません。 これは、多くの異なるコレクション クラスとコントロール クラスの引数として受け入れられます。
手順の例
次の例では、これらのインターフェイスの使用方法を示します。 IComparer
とIComparable
を示すために、Car
という名前のクラスが作成されます。 Car
オブジェクトには、make プロパティと year プロパティがあります。 make フィールドの昇順の並べ替えは、 IComparable
インターフェイスを介して有効になり、make フィールドの降順の並べ替えは、 IComparer
インターフェイスを介して有効になります。 IComparer
を使用して、year プロパティに対して昇順と降順の両方の並べ替えが提供されます。
Visual C# で、新しいコンソール アプリケーション プロジェクトを作成します。 アプリケーションに ConsoleEnum という名前を付けます。
Program.csHost.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(); } } }
プロジェクトを実行します。 Console ウィンドウに次の出力が表示されます。
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