IComparable Visual CSharp で と IComparer インターフェイスを使用する

この記事では、Visual C# での インターフェイスと IComparable インターフェイスのIComparer使用について説明します。

元の製品バージョン: 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;
   }
}

注:

メソッドには IComparer.Compare 、3 番目の比較が必要です。 10、または -1 は、1 つの値が他の値より大きい、等しい、またはそれより小さいかどうかに応じて返されます。 並べ替え順序 (昇順または降順) は、このメソッドの論理演算子を切り替えることによって変更できます。

2 番目の手順は、オブジェクトのインスタンスを返すメソッドを IComparer 宣言することです。

public static IComparer SortYearAscending()
{
   return (IComparer) new SortYearAscendingHelper();
}

この例では、 を受け入れるオーバーロードされた Array.Sort メソッドを呼び出すときに、 オブジェクトを 2 番目の引数として使用します IComparer。 の IComparer 使用は配列に限定されません。 これは、さまざまなコレクション クラスとコントロール クラスの引数として受け入れられます。

ステップ バイ ステップの例

次の例では、これらのインターフェイスの使用方法を示します。 と を示IComparerすために、 という名前Carのクラスが作成IComparableされます。 オブジェクトには Car 、make プロパティと year プロパティがあります。 make フィールドの昇順の並べ替えはインターフェイスを IComparable 介して有効になり、make フィールドの降順の並べ替えはインターフェイスを IComparer 介して有効になります。 を使用 IComparerして、year プロパティに対して昇順と降順の両方の並べ替えが提供されます。

  1. Visual C# で、新しいコンソール アプリケーション プロジェクトを作成します。 アプリケーションに ConsoleEnum という名前を付けます

  2. 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();
           }
       }
    }
    
  3. プロジェクトにクラスを追加します。 Car クラスに名前を付 けます

  4. 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();
          }
    
       }
    }
    
  5. プロジェクトを実行します。 コンソール ウィンドウに次の出力が表示されます。

    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