Sortのドキュメントによると、「comparer の実装がソート中にエラーを引き起こした場合、Sort は ArgumentException をスローします。たとえば、アイテムをそれ自体と比較するときに、comparer が 0 を返さない場合があります。」
与えられた例とは別に、そうでなければいつ起こるか誰か教えてもらえますか?
並べ替えアルゴリズム (QuickSort) は、予測可能な IComparer 実装に依存しています。BCL で数十層の間接化を行った後、次の方法に行き着きます。
public void Sort(T[] keys, int index, int length, IComparer<T> comparer)
{
try
{
...
ArraySortHelper<T>.QuickSort(keys, index, index + (length - 1), comparer);
}
catch (IndexOutOfRangeException)
{
...
throw new ArgumentException(Environment.GetResourceString("Arg_BogusIComparer", values));
}
}
QuickSort の実装をもう少し進めると、次のようなコードが表示されます。
while (comparer.Compare(keys[a], y) < 0)
{
a++;
}
while (comparer.Compare(y, keys[b]) < 0)
{
b--;
}
基本的に、IComparer が、ArgumentException にラップされている IndexOutOfRangeException をスローして、Quicksort 呼び出しを誤動作させた場合。
悪い IComparer の別の例を次に示します。
class Comparer: IComparer<int>
{
public int Compare(int x, int y)
{
return -1;
}
}
したがって、短い答えは、 IComparer 実装がドキュメントで定義されているように一貫して値を比較しないときはいつでも、ということです。
2 つのオブジェクトを比較し、一方が他方よりも小さいか、等しいか、または大きいかを示す値を返します。
今日これに遭遇し、調査したところ、比較子が x と y が同じ object への参照で呼び出されていることがあり、比較子が 0 を返していないことがわかりました。それを修正すると、例外が発生しなくなりました。
HTH、
エリック