web-dev-qa-db-ja.com

IComparableインターフェースは古くなった/「有害」ですか?

IComparableは一方向にしか機能しません

Employeeクラスがあるとします。 1つのビューで、すべてのEmployeesを名前でソートし、別のビューでアドレスで表示したいとします。どのようにしてそれを達成しますか? IComparableではなく、少なくとも慣用的な方法ではありません。

IComparableのロジックが間違った場所にあります

このインターフェースは、.Sort()を呼び出すことによって使用されます。 Customerを名前で並べ替えて表示するビューでは、並べ替え方法を示すコードはまったくありません。
一方、Customerクラスは、それがどのように使用されるかを想定しています-この場合、名前でソートされたリストで使用されます。

IComparableは暗黙的に使用されます

他の方法と比較すると、比較ロジックがどこで使用されているか、または使用されているかどうかを確認することは非常に困難です。あなたの標準IDEで、Customerクラスから始めると仮定すると、

  1. Customerへのすべての参照を検索します
  2. リストで使用されている参照を見つける
  3. これらのリストに.Sort()が呼び出されているかどうかを確認します

さらに悪いことに、まだ使用されているIComparable実装を削除しても、エラーや警告は表示されません。あなたが得る唯一のものは、あなたが考えるにはあまりにも曖昧であったすべての場所での間違った行動です。

これらの問題を組み合わせ、さらに要件を変更する

私がこれについて考えるようになったまさにその理由は、それが私にとってうまくいかなかったからです。私は2年間、アプリケーションでIComparableを楽しく使用しています。今、要件が変更され、事物は2つの異なる方法でソートされる必要があります。前のセクションで説明した手順を実行するのは面白くないことに気付きました。

質問

これらの問題により、IComparableIComparerまたは.OrderBy()よりも劣ると見なされ、代替手段ではより適切に提供されない有効なユースケースが表示されなくなる。
IComparerまたはLINQを使用するのが常に良いですか、それともここに表示されていない利点/使用例がありますか?

11
R. Schmitz

IComparableには、あなたが述べた制限があります。これは、.NET Framework 1.0ですでに使用可能であったインターフェースであり、これらの代替機能とLinqは使用できませんでした。そう、そうです、それは主に後方互換性のために保持されている古いフレームワーク要素としてそれを見るかもしれません。

ただし、多くの単純なデータ構造では、1つのソート方法でおそらく十分または自然です。これらの場合、順序関係を実装する1つの正規の場所があることは、場所全体でOrderByを呼び出すたびに常に同じロジックを繰り返すのではなく、コードをDRYに保つための良い方法です。

あなたが書いたように、あなたは「今から2年間アプリケーションでIComparableを楽しく使っています」ので、長い間あなたによく役に立ったように思えます。 Sortへのすべての呼び出しを検証、変更、テストする必要がある場合、これは多くの場所で同じ種類のソートロジックを実行していたことを示している可能性があります。これはIComparableのせいではありません。したがって、これは、このロジックを1か所に集中化して、コードをより乾燥させる機会になる可能性があります。

14
Doc Brown

IComparableについてのあなたの意見に同意します

Array.Sort()の備考を見てください

  • 配列の各要素は、配列内の他のすべての要素と比較できるようにIComparableインターフェイスを実装する必要があります。 (または例外がスローされます)
  • ソートが正常に完了しない場合、結果は未定義です。

おそらく今はやる気はないでしょう! object.Equals()を検討して、オブジェクトが「同じ」かどうかを確認するためにオブジェクトを相互に比較できるようにする、すべてのオブジェクトのメソッド

あなたはすでにそれを持っていますが、Array.Sort()の追加を任されています。追加したい場合はobject.Compare(object)

1
Ewan