コレクションのルックアップ。辞書に代わります
-
20-08-2019 - |
質問
TimeSheetActivityクラスは、割り当てのコレクションを持っています。配分はこのような何かを探しているだけでなく、ドメイン内の他のオブジェクトによって使用されている値オブジェクトです。
public class Allocation : ValueObject
{
public virtual StaffMember StaffMember { get; private set; }
public virtual TimeSheetActivity Activity { get; private set; }
public virtual DateTime EventDate { get ... }
public virtual TimeQuantity TimeSpent { get ... }
}
同じAllocation.EventDateのための重複割り当てが許可されていません。クライアントは、活動への配分を作るしようとしたときので、チェックが同じAllocation.EventDateためのコレクション内の割り当てがすでに存在しているかどうかを確認するために行われます。そうでない場合、新しい割り当てをコレクションに追加されますが、もしそうであれば、既存の割り当ては、新しいものに置き換えられます。
私は現在、キーとしてAllocation.EventDateで、コレクションを維持するために辞書を使用しています。これは、ドメインの正常に動作しますが、キーが既に値の一部であるという事実は、「悪臭」そのものではない場合、私は思ったんだけど。
私はまた、辞書の値以外のものを永続化する理由がありません。私はNHibernateはを使用しているので、私はそれを行ういくつかのカスタムタイプを記述する必要があり、そしてそれはまた、私は、コレクションの異なるタイプを使用する必要があります手掛かりである場合、私は思ったんだけど。 (それはまた、割り当てクラスの仮想プロパティの理由です)。
私は、専用のEqualityComparerとHashSetのだろうと思っています主な代替手段を。
あなたはどう思いますか?
乾杯、 Berryl
解決
HashSet<Allocation>
を行うには、外部比較子を使用する場合は、、あなたは辞書で再キーイング値なしで日付を変更していない非常に慎重でなければならないであろう。あなたはこの問題のいずれかの方法を持っているが、それは(少なくともDictionary<,>
と、まだ、独自のキーと値を追跡することができるようになります)可変性によって悪化します。あなたは決して再び値を見ていない危険がキーの一部として変更可能な値を持つ...
SortedList<,>
を使用しました。 > 他のヒント
私は、キーが値の一部であるという事実は、必ずしも問題ではないと思います。私の経験では、それはかなり頻繁に辞書用ケースです。適切な等値比較でHashSet
は確かに限り、あなたが特定のEventDate
と、現在のオブジェクトで取得するために必要なことはありませんよう、働くだろう。それは潜在的に...
あなたはやや漠然とした方法で、現在だけで心配している、またはあなたは、これはあなたを噛まないかもしれない方法についての具体的な疑いを持っていますか?
標準ライブラリを使用して、私の知っている何よりよい解決策はありません。しかし、私はまた、この種のコードは、「悪臭」であることを感じましたが、それは理由BCLはなく、あなたのコード内のコレクションクラスのです。
MSは、その代わりに、辞書のジェネリックSets<TKey, TData> where TData: IKeyed<TKey>
かを作成していない理由は、このキーがデータの一部であるようなデータ構造を実装できるようになるので、私は、知りません。 KeyValuePair<TKey, TValue>: IKeyed<TKey>
だけのヘルパー構造このインタフェースを実装しているので、我々は今それを持っているように、同一の辞書機能を作成することを可能にするだろう。
また、彼らは宣言型不変タイプの概念を追加し、これを可能にジェネリック型制約しなかった理由は、これは必ず鍵は、実行時にそのハッシュコードを変更しません行うことができますので、私は、不思議(小さな暴言を続行します) (一つは、いくつかの可変オブジェクトにGetHashCode()
とEquals()
を実装する場合、現在発生する可能性がある)。