C#ソート比較
12950 ワード
C#が同等性比較仕様を定義したのと同様に、C#もソート比較仕様を定義し、あるオブジェクトと別のオブジェクトの優先順位を決定します.ソート仕様は次のとおりです. IComparableインタフェース(IComparableインタフェースおよびIComparableインタフェースを含む) >および<演算子 ソートアルゴリズムを実装する必要がある場合は、IComparableインタフェースを使用します.次の例では、Array.Sort静的メソッドはSystemのため呼び出すことができる.StringクラスはIComparableインタフェースを実現した.
.NET Frameworkには、プラグイン式のソートプロトコルであるIComparerインタフェースも用意されています.IComparableインタフェースとIComparerインタフェースの違いは、IEquatableインタフェースとIEqualityComparerインタフェースと似ています(IEquableインタフェースとIEqualityComparerインタフェースについては、C#等化:http://www.cnblogs.com/yang_sy/p/3582946.htmlを参照してください).
1.IComparableインタフェース
IComparableインタフェースの定義は次のとおりです.インタフェースの効率はICompareインタフェースよりも高い.上の2つのインタフェースのCompareToメソッドは、次のように実行されます. aがbの後ろに並んでいる場合、a.CompareTo(b)は1 を返す. aと異なる場合は、0 を返します. aが前に並んでいない場合は-1 に戻る.
次のコードの例を見てみましょう.インタフェースを実現しています.多くのカスタムタイプも同様にインタフェースを実装しており、ソートが容易です.
IComarableとEquals
Equalsメソッドを書き換え、IComparableインタフェースを実装したタイプを仮定します.では、Equalsがtrueを返すと、CompareToは0を返すことを望んでいます.Equalsがfalseを返すと、CompareToは任意の値を返すことができます.
言い換えれば、等化性は対比性よりも厳しい.逆はできない.したがって、CompareToが「2つのオブジェクトが等しい」と言うと、Equalsは「この2つのオブジェクトが必ずしも等しいとは限らない」と言います.良い例はシステムですStringクラス.String.Equalsメソッドと==演算子は、シーケンス番号ソート規則を使用して文字列を比較します.つまり、各文字のUnicodeの値でソートします.StringCompareToメソッドは,それほど厳密ではない文化領域(culture-dependent)に基づいて比較する.ほとんどのコンピュータでは、文字ǖとṻ,EqualsはFalseを返し,CompareToは0を返す.
IComparerインタフェースを介して、特定のソートアルゴリズムを完了することができます.カスタムIComparerインタフェースの実装は,CompareToとEqualsメソッドの違いをさらに増大させた.例えば、大文字と小文字を区別しない文字列比較器は、Aとaに対して0を返す.これも裏から証明されていますが、ComparToの方法はEqualsの方法ほど厳しくありません.
2.<および>演算子
<和>演算子を定義するタイプがあります.たとえば、次のようになります.
同様に、<和>演算子が1つのタイプに再ロードされると、IComparableインタフェースの実装も要求され、逆に必要とされない.実際、ほとんどはNETタイプはIComparableインタフェースを実装し、<和>演算子は再ロードされません.これは、同等性の比較とは異なります.等しい比較を実現する場合、Equalsメソッドが再ロードされた場合、一般的には==演算子 が再ロードされる.で並べ替え比較を行う場合、CompareToメソッドが実装されている場合、<演算子および>演算子 の再ロードは一般的に要求されない.
一般に、<演算子および>演算子を再ロードする必要があるのは、次の場合のみです.のタイプ自体は、このような概念 より大きいおよび小さいを含む.前後順比較を実行する方法は唯一の である.結果は、文化的領域(Cultures)の変化に伴って変化しない .
System.Stirngタイプは最後の1つを満たしていないため、stringは>アクションおよび<アクションをサポートしません.したがって「beck」>「Anne」では、コンパイル時にエラーが投げ出されます.
3.IComparableインタフェースの実装
次のインスタンスコードでは、構造Noteは、IComparableインタフェースを実装し、<演算子と>演算子を再ロードする音楽の注釈を表します.インスタンスの完全性のためにEqualsとGetHashCodeメソッドも書き換え,==と!演算子、この例では、ソート比較を全面的に理解することができます.
string[] colors={"Green", "Red", "Blue"};
Array.Sort(colors)
foreach(string c in colors)
Console.Write(c+ " ");
<和>演算子は、数値タイプの比較に一般的に使用されるため、特殊です.演算子より大きいか小さいかは静的に解析されるため、複雑な計算のシーンに適用される効率的なコードを「生成」します..NET Frameworkには、プラグイン式のソートプロトコルであるIComparerインタフェースも用意されています.IComparableインタフェースとIComparerインタフェースの違いは、IEquatableインタフェースとIEqualityComparerインタフェースと似ています(IEquableインタフェースとIEqualityComparerインタフェースについては、C#等化:http://www.cnblogs.com/yang_sy/p/3582946.htmlを参照してください).
1.IComparableインタフェース
IComparableインタフェースの定義は次のとおりです.
public interface IComparable
int CompareTo(Object obj);
}
public interface IComparable<in T>
{
int CompareTo(T other);
}
この2つのインタフェースは、同じ機能を定義します.値タイプの場合、IComparable次のコードの例を見てみましょう.
IList<Staff> staffs = new List<Staff>
{
new Staff{FirstName="AAA", Title="Manager", Dept="Sale"},
new Staff{FirstName="BBB", Title="Accountant", Dept="Finance"},
new Staff{FirstName="CCC", Title="Accountant", Dept="Finance"},
};
Console.WriteLine("BBB".CompareTo(staffs[0].FirstName)); // 1
Console.WriteLine("BBB".CompareTo(staffs[1].FirstName)); // 0
Console.WriteLine("BBB".CompareTo(staffs[2].FirstName)); // -1
C#のほとんどの基本タイプは、IComparableインタフェースとIComparableIComarableとEquals
Equalsメソッドを書き換え、IComparableインタフェースを実装したタイプを仮定します.では、Equalsがtrueを返すと、CompareToは0を返すことを望んでいます.Equalsがfalseを返すと、CompareToは任意の値を返すことができます.
言い換えれば、等化性は対比性よりも厳しい.逆はできない.したがって、CompareToが「2つのオブジェクトが等しい」と言うと、Equalsは「この2つのオブジェクトが必ずしも等しいとは限らない」と言います.良い例はシステムですStringクラス.String.Equalsメソッドと==演算子は、シーケンス番号ソート規則を使用して文字列を比較します.つまり、各文字のUnicodeの値でソートします.StringCompareToメソッドは,それほど厳密ではない文化領域(culture-dependent)に基づいて比較する.ほとんどのコンピュータでは、文字ǖとṻ,EqualsはFalseを返し,CompareToは0を返す.
IComparerインタフェースを介して、特定のソートアルゴリズムを完了することができます.カスタムIComparerインタフェースの実装は,CompareToとEqualsメソッドの違いをさらに増大させた.例えば、大文字と小文字を区別しない文字列比較器は、Aとaに対して0を返す.これも裏から証明されていますが、ComparToの方法はEqualsの方法ほど厳しくありません.
2.<および>演算子
<和>演算子を定義するタイプがあります.たとえば、次のようになります.
bool after2010 = DateTime.Now > new DateTime(2010, 1, 1);
Console.WriteLine(after2010);
<和>演算子を実装した後、<和>演算子がIComparableインタフェースと一致することを保証する必要があります.これも.NET Frameworkの標準.同様に、<和>演算子が1つのタイプに再ロードされると、IComparableインタフェースの実装も要求され、逆に必要とされない.実際、ほとんどはNETタイプはIComparableインタフェースを実装し、<和>演算子は再ロードされません.これは、同等性の比較とは異なります.
一般に、<演算子および>演算子を再ロードする必要があるのは、次の場合のみです.
System.Stirngタイプは最後の1つを満たしていないため、stringは>アクションおよび<アクションをサポートしません.したがって「beck」>「Anne」では、コンパイル時にエラーが投げ出されます.
3.IComparableインタフェースの実装
次のインスタンスコードでは、構造Noteは、IComparableインタフェースを実装し、<演算子と>演算子を再ロードする音楽の注釈を表します.インスタンスの完全性のためにEqualsとGetHashCodeメソッドも書き換え,==と!演算子、この例では、ソート比較を全面的に理解することができます.
internal struct Note : IComparable, IComparable<Note>, IEquatable<Note>
{
private int semitonesFromA;
public int SemitonesFromA
{
get { return semitonesFromA; }
}
public Note(int semitonesFromA)
{
this.semitonesFromA = semitonesFromA;
}
// generic IComparable<T>
public int CompareTo(Note other)
{
if (Equals(other))
return 0;
return SemitonesFromA.CompareTo(other.SemitonesFromA);
}
// non-generic IComaparable
public int IComparable.CompareTo(object other)
{
if (!(other is Note))
throw new InvalidOperationException("CompareTo: Not a note");
return CompareTo((Note)other);
}
public static bool operator <(Note n1, Note n2)
{
return n1.CompareTo(n2) < 0;
}
public static bool operator >(Note n1, Note n2)
{
return n1.CompareTo(n2) > 0;
}
// for IEquatable
public bool Equals(Note other)
{
return this.SemitonesFromA == other.SemitonesFromA;
}
// override Object.Equals
public override bool Equals(object other)
{
if (!(other is Note))
throw new InvalidOperationException("CompareTo: Not a note");
return Equals((Note)other);
}
public override int GetHashCode()
{
return SemitonesFromA.GetHashCode();
}
public static bool operator ==(Note n1, Note n2)
{
return n1.Equals(n2);
}
public static bool operator !=(Note n1, Note n2)
{
return !(n1 == n2);
}
}