web-dev-qa-db-ja.com

IComparableとIComparerの違い

IComparableIComparerインターフェースの違いは何ですか? Array.Sort()メソッドで常にこのインターフェイスを使用する必要がありますか

49
Raghav55

名前が示すように、IComparable<T>は読み取ります私は匹敵しますIComparable<T>Tに対して定義すると、現在のインスタンスを同じタイプの別のインスタンスとcompareできます。 IComparer<T>は読み取ります私は比較者です、私は比較しますIComparer<T>は、通常Tのインスタンスのスコープ外で、Tの2つのインスタンスを比較するために使用されます。

の目的は、最初は混乱する可能性があります。定義から、IComparable<T>(クラスT自体で定義)がソートのロジックを提供するための事実上の標準である必要があることは明らかです。 List<T>などのデフォルトのSortなどはこれに依存しています。 TIComparer<T>を実装しても、通常の並べ替えには役立ちません。その後、T以外の他のクラスにIComparable<T>を実装する価値はほとんどありません。この:

class MyClass : IComparable<T>

めったに意味がありません。

一方

class T : IComparable<T>
{
    public int CompareTo(T other)
    {
        //....
    }
}

それがどのように行われるべきかです。

IComparer<T>は、カスタムルールに基づく並べ替えが必要な場合に役立ちますが、一般的な規則としては役立ちません。たとえば、Personのクラスでは、ある時点で、年齢に基づいて人を並べ替える必要がある場合があります。その場合、次のことができます。

class Person
{
    public int Age;
}

class AgeComparer : IComparer<Person>
{
    public int Compare(Person x, Person y)
    {
        return x.Age - y.Age;
    }
}

AgeComparerは、Ageに基づいてリストをソートするのに役立ちます。

var people = new Person[] { new Person { age = 23 }, new Person(){ age = 22 } };
people.Sort(p, new AgeComparer()); //person with age 22 comes first now.

同様に、TIComparer<T>は意味をなしません。

class Person : IComparer<Person>

確かにこれは動作しますが、見た目が良くなく、ロジックを無効にします。

通常、必要なのはIComparable<T>です。また、理想的には、異なる基準に基づいて複数のIComparable<T>が可能ですが、IComparer<T>を1つだけ持つことができます。

IComparer<T>およびIComparable<T>は、比較/ソートではなく、同等性のテストに使用されるIEqualityComparer<T>およびIEquatable<T>とまったく同じです。良いスレッド ここ 私がまったく同じ答えを書いたところ:)

86
nawfal
  • IComparable-CompareTo()メソッドを使用してオブジェクトのインターフェイスを定義します。CompareTo()メソッドは、同じタイプの別のオブジェクトを取得し、現在のオブジェクトと渡されたオブジェクトを比較します。オブジェクトへの比較を内部化し、よりインラインの比較操作を可能にし、タイプのオブジェクトを比較する論理的な方法が1つだけある場合、または圧倒的に一般的なデフォルトの方法がある場合に役立ちます。
  • IComparer-(IComparableを実装する必要のない)別のタイプの2つのオブジェクトを取得して比較するCompare()メソッドを使用してインターフェイスを定義します。これは比較を外部化し、型の2つのオブジェクトを比較する多くの実行可能な方法がある場合、または型がIComparableを実装していない場合(またはIComparable実装が希望と異なる方法を比較している場合)に便利ですそのタイプのソースを制御できます。
35
KeithS

私が読んだ最高の説明は、「ソートされるオブジェクトはIComparableを実装し、オブジェクトをソートするクラスはIComparerを実装します」です。 ( ソース

並べ替えようとしているオブジェクトがIComparableを実装していない場合、IComparerを実装するクラスを作成し(比較のためにこれらのオブジェクトタイプを受け入れ)、Array.Sort()メソッドに渡す必要があります。

15
Ken Pespisa

IComparableは、オブジェクトのデフォルトのソート順を提供するために使用されます。

IComparerは、追加の比較メカニズムを提供します。

この記事を参照してください。 http://support.Microsoft.com/kb/320727

6
niknowj

IComparerは、指定された2つのオブジェクトを比較します。 IComparableは、他のオブジェクトと比較するために、比較されるオブジェクトによって実装されます。

オブジェクトを並べ替えるためにIComparableを実装することをお勧めします。 IComparableは、さまざまな基準による並べ替え(たとえば、オブジェクト内の選択可能なフィールドによる並べ替え)に役立ちます。

次も参照してください。 IComparable <T>とIComparer <T>を使用する場合

1
Sean Edwards

IComparableを実装するクラスのインスタンスであるオブジェクトは、他のオブジェクトと比較できます。 (IComparableを "私は比較できます。"と読みます。)これを行うこのインターフェイスのメソッドはCompareToです。これは、そのようなクラスのインスタンスに自分自身を他のオブジェクトと比較する方法を知りたい場合に便利です。

IComparerを実装するクラスのインスタンスであるオブジェクトを使用して、オブジェクトのペアを比較できます。 (IComparerを「比較できます」と読みます。)これを行うこのインターフェイスのメソッドはCompareです。これは、比較するオブジェクトのクラスから比較ロジックを分離したい場合に便利です。オブジェクトを比較するさまざまな方法がある場合にこれを使用する1つのケース(この大文字と小文字を区別しない文字列比較)。

0
jason