回答:
まあそうではありません、非常に同じことIComparer<T>
ながら、2つの異なるオブジェクトを比較することのできるタイプに実装されているIComparable<T>
同じ種類の他のインスタンスと自分を比較することができますタイプに実装されています。
IComparable<T>
別のインスタンスがインスタンスにどのように関連しているかを知る必要があるときに使用する傾向がありthis
ます。 比較の外に立つIComparer<T>
ので、コレクションをソートするのに役立ちIComparer<T>
ます。
IComparable
として、私は比較可能です。つまり、他の何かと比較することができます。そして、読みIComparer
として、私は比較演算子だ、私は単純に比較し、私はいくつかのことを比較することを意味します。
エンティティによって異なります。たとえば、「学生」のようなクラスの場合、名前に基づいてIComparableを持つことは理にかなっています。
class Student : IComparable
{
public string Name { get; set; }
public int MathScore { get; set; }
public int EnglishScore { get; set; }
public int TotalScore
{
get
{
return this.MathScore + this.EnglishScore;
}
}
public int CompareTo(object obj)
{
return CompareTo(obj as Student);
}
public int CompareTo(Student other)
{
if (other == null)
{
return 1;
}
return this.Name.CompareTo(other.Name);
}
}
しかし、教師 'A'がMathScoreに基づいて生徒を比較したいとし、教師 'B'がEnglishScoreに基づいて生徒を比較したい場合。IComparerを個別に実装することをお勧めします。(より戦略パターンのように)
class CompareByMathScore : IComparer<Student>
{
public int Compare(Student x, Student y)
{
if (x.MathScore > y.MathScore)
return 1;
if (x.MathScore < y.MathScore)
return -1;
else
return 0;
}
}
それはすべて、型が変更可能かどうかによって異なります。IComparableは、変更できない型にのみ実装する必要があります。IComparableを実装する場合は、==、!=、<、および>演算子と共にEqualsをオーバーライドする必要があることに注意してください(コード分析警告CA1036を参照)。
このブログ投稿からDave Gを引用:
しかし、正しい答えは、オブジェクトが変更可能な場合はIComparableではなくIComparerを実装し、必要に応じてIComparerのインスタンスを並べ替え関数に渡すことです。
IComparerは、その時点での並べ替えに使用される使い捨てオブジェクトにすぎないため、オブジェクトには任意の変更可能なセマンティクスを設定できます。さらに、Equals、GetHashCode、または==を使用する必要はなく、推奨もされていません。好きなように自由に定義できます。
最後に、異なるフィールドまたは異なるルールでソートするために、タイプに複数のIComparerを定義できます。これは、1つの定義に固執するよりもはるかに柔軟です。
つまり 、値の型にはIComparableを使用し、参照型にはIComparerを使用します。
ストーリーによる簡単な説明
高校バスケットボール。チームのための校庭ピックです。私のチームで最も背が高い/最高の/最速の人々を獲得したいと思います。私は何をしますか?
IComparerインターフェイス-2人を別々の人と比較する
Compare(Fred, John)
そしてそれは誰がより良いのかを吐き出します。IComparableはどうですか?-自分を他の人と比較する
最近FBに行ったことがありますか?あなたは他の人々がクールなことをしているのを見ます:私はそれほどクールではない何かをしている間、世界を旅し、発明を作ります-私たちがやっていることはIComparableインターフェースを利用しています。
Comparerクラスはどうですか?
Comparerクラスは、IComparerインターフェイスを実装する抽象基本クラスです。具体的な実装を行うには、このクラスから派生する必要があります。とにかく、マイクロソフトでは、IComparerインターフェイスを実装するのではなく、Comparerクラスを使用することをお勧めします。
Comparerクラスは、IComparer.Compareメソッドの明示的なインターフェイス実装とオブジェクトのデフォルトの比較子を取得するDefaultプロパティを提供するため、IComparerインターフェイスを実装する代わりに、Comparerクラスから派生することをお勧めします。
ストーリーがあなたの記憶に役立つことを願っています。
他の人が言ったように、彼らは同じことをしません。
いずれにせよ、最近はIComparerを使わない傾向があります。なぜ私は?その責任(2つのオブジェクトを比較するために使用される外部エンティティ)は、ほとんどのLINQのメソッドが機能するのと同様に、ラムダ式を使用してよりクリーンに処理できます。比較するオブジェクトを引数として取り、ブール値を返す簡単なラムダを記述します。また、オブジェクトが固有の比較操作を定義している場合は、代わりにIComparableを実装できます。
IComparableは、オブジェクトを別のオブジェクトと比較できると言います。IComparerは、任意の2つの項目を比較できるオブジェクトです。
IComparerは、配列の並べ替えに使用されるインターフェイスです。このインターフェイスは、2つのオブジェクトを比較するCompare(T x、T y)メソッドの実装をクラスに強制します。このインターフェースを実装したクラスのインスタンスは、配列のソートに使用されます。
IComparableは、同じタイプの2つのオブジェクトを比較する必要があるタイプで実装されているインターフェースです。この比較可能なインターフェースにより、クラスは次のメソッドCompareTo(T obj)を実装します。
IEqualityComparerは、Equalであるかどうかに関係なくオブジェクトを見つけるために使用されるインターフェイスです。これを、コレクション内のオブジェクトのDistinctを見つける必要があるサンプルで確認します。このインターフェイスは、メソッドEquals(T obj1、T obj2)を実装します
今度はEmployeeクラスがある例を取り上げます。このクラスに基づいて、コレクションを作成します。現在、次の要件があります。
配列クラス2を使用して配列をソートします。Linqを使用してコレクションが必要です。重複を削除し、上位から下位に並べ替え、従業員IDを1つ削除します
abstract public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { set; get; }
}
public enum SortType
{
ByID,
BySalary
}
パブリッククラスEmployeeIdSorter:IComparer {public int Compare(Employee x、Employee y){if(x.Id <y.Id)return 1; else if(x.Id> y.Id)は-1を返します。それ以外の場合は0を返します。}}
public class EmployeeSalarySorter : IComparer<Employee>
{
public int Compare(Employee x, Employee y)
{
if (x.Salary < y.Salary)
return 1;
else if (x.Salary > y.Salary)
return -1;
else
return 0;
}
}
詳細については、以下を参照してください http://dotnetvisio.blogspot.in/2015/12/usage-of-icomparer-icomparable-and.html