.NET Framework 4より、Tuple<T1, T2>、Tuple<T1, T2, T3>などのタプル(組、Tuple)が導入されました。 これに伴い、構造を比較するためのインターフェイスIStructuralComparableおよびIStructuralEquatableが導入され、タプル型やArrayクラスで実装されています。
IStructuralEquatable
IStructuralEquatable(System.Collections名前空間)は構造上の等価性を比較するメソッドを提供するインターフェイスです。 例えば、配列を一つの構造体ととらえたとき、同一の要素数(長さ)の配列は同じ構造を持っていると考えることが出来、構造内の個々の要素が等しければ構造的に等しいと定義することが出来ます。
構造の比較を行うIStructuralEquatable.Equalsメソッドは、比較対象となるオブジェクトと、等価性の比較を行うためのIEqualityComparerの二つを引数に取ります。 .NET Framework 4以降では、ArrayクラスはIStructuralEquatableインターフェイスを実装しているため、構造の比較が行えるようになっています。 ただし、IStructuralEquatableのメソッドは明示的な実装となっているため、IStructuralEquatableにキャストしない限りメソッドを呼び出すことは出来ません。 次の例は、配列同士をIStructuralEquatable.Equalsメソッドで比較する例です。
Array.Equalsメソッドはオーバーライドされていないためオブジェクト同士の参照の比較しか行いませんが、Array.IStructuralEquatable.Equalsメソッドでは構造の比較を行うようになっているため、上記のような結果となります。 要素数とすべての要素が等しければ構造上等しいとなるのに対し、要素数またはいずれかの要素が異なれば構造上異なると判断されます。
Arrayとは異なり、TupleのEqualsメソッドは構造の比較を行うようになっているため、必ずしもIStructuralEquatableにキャストする必要はありません。
なお、System.Collections名前空間やSystem.Collections.Generic名前空間にあるList<T>などのコレクションクラスにはIStructuralEquatableが実装されていないため、この様な比較を行うことは出来ません。 要素数を調べ、個々の要素に対して等しいかどうか比較を行う必要があります。
IStructuralComparable
IStructuralComparable(System.Collections名前空間)はIStructuralEquatableと同様に構造上の大小関係を比較するメソッドを提供するインターフェイスです。
構造の比較を行うIStructuralComparable.CompareToメソッドは、比較対象となるオブジェクトと、大小関係の比較を行うためのIComparerの二つを引数に取ります。
StructuralComparisons.StructuralComparerプロパティを参照すると、構造の比較を行うIComparerを取得することが出来ます。 次の例では、ジャグ配列を作成し、Array.Sortメソッドでソートしています。
なお、StructuralComparisons.StructuralComparerを使ってソート出来るのは、ジャグ配列内の各配列の長さが等しい場合に限られる点に注意が必要です。 各配列の長さが異なるジャグ配列のソートについてはジャグ配列・多次元配列のソートで解説しています。
一方、Arrayとは異なり、TupleのCompareToメソッドは構造の比較を行うようになっているため、必ずしもStructuralComparisons.StructuralComparerを指定する必要はありません。