2009-06-27 9 views
2

TimeSheetActivityクラスには、割り当てのコレクションがあります。同じAllocation.EventDateためコレクションの検索。 Dictionaryの代替語

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をキーとしてコレクションを管理するために辞書を使用しています。それはドメインでうまく動作しますが、キーが既に値の一部であるという事実自体が「悪臭」ではないかと思います。

また、辞書の値以外のものを保持する理由もありません。私はNHibernateを使用しているので、私はそれを行ういくつかのカスタムタイプを書く必要があるかもしれません、そして、それはまた別のタイプのコレクションを使用する必要があるという手掛かりですか? (これもAllocationクラスの仮想プロパティの理由です)。

私が考えている主な代替案は、専用のEqualityComparerを持つHas​​hSetです。

あなたはどう思いますか?

乾杯、 Berryl

+0

これは非常に古い質問です。しかし、なぜ誰もリンクされたリストを提案しなかったのだろうか。なぜなら、これは辞書が内部的に矛盾するハッシュのために使うものなのだから。 'Dictionary 'が重複するキーを持つことができない唯一の理由は、あなたが見たときに何を返すべきかを知らないためです。 (Btw。構造体を構造体にして、パフォーマンスを大幅に節約してください) – Aidiakapi

答えて

3

HashSet<Allocation>を外部の比較処理に使用する場合は、辞書の値を再入力しないで日付を変更しないように注意する必要があります。あなたはどちらの方法でもこの問題を抱えていますが、少なくともDictionary<,>ではそれでも独自のキーと値を追跡することができます。キーの一部として変更可能な値を使用すると、値が再び表示されることはありません...

私はこれまでにスケジュールシステムで作業していましたが、実際にはSortedList<,>を使用しました。データを順番に欲しがり、データがかなり均一であればバイナリ検索が可能です。

+0

SortedListのヒントをありがとう。 Cheers – Berryl

3

は、私は、キーが値の一部であるという事実は、必ずしも問題ではないと思います。私の経験では、それはかなり頻繁に辞書の場合です。特定のEventDateを持つ現在のオブジェクトを取得する必要がない限り、適切な等価比較機能を持つHashSetが確実に機能します。それは潜在的に可能なことのように思えます...

あなたは現在、やや曖昧なやりかたに懸念していますか?これがどのようにあなたを噛んでいるかについて具体的な疑念はありますか?

+0

キーの値の一部であるという曖昧な心配を本当に検証したかったのです。真実は、辞書がうまく動作し、使いやすいと言われます。 私はあなたの本のパート1を終えました.BTW ...あなたは素晴らしい作家です! – Berryl

2

標準ライブラリを使用すると、私が知っているより良い解決策はありません。しかし、私はこの種のコードが「悪臭」であると感じましたが、それはBCLのコレクションクラスであり、コードではないからです。

なぜMSは、キーがデータの一部であるようなデータ構造を実装できるようにするために、ディクショナリの代わりに<TKey, TData> where TData: IKeyed<TKey>かそれ以降の汎用セットを作成しなかったのか分かりません。 KeyValuePair<TKey, TValue>: IKeyed<TKey>は、このインタフェースを実装するヘルパー構造にすぎず、今のところ同じ辞書機能を作成することができます。

また、宣言的な不変型の概念を追加せず、これを可能な総称型制約にしなかったのはなぜだろうか。なぜなら、これはキーがそのハッシュコードを変更していないことを確認できるからだ。実行時(ある変更可能なオブジェクトにGetHashCode()Equals()を実装している場合に発生する可能性があります)。

+0

辞書タイプのオブジェクトをディクショナリキーとして使用しても問題ありません。ただし、その方法で使用されるオブジェクト*インスタンス*は、ディクショナリに格納されている間に変更される可能性のあるコードにはさらされません。変更可能な型の不変のインスタンスを維持することに関して、フレームワーク/コンパイラの支援を受けることは有益ですが、型システムにいくらかの大幅な変更が必要になります。 – supercat

+0

@supercat、明らかに、変更可能なオブジェクトが扱われ、不変なオブジェクトとして使用されている場合は、それは問題ありません。私の主張は、コンパイラが、キーとして既に使用されているのと同じオブジェクトを渡しても、キーオブジェクトのどのような突然変異もルックアップを破ることはできない、ということです。 'GetHashCode()'は辞書またはハッシュテーブルの外観間違ったバケツで保障措置がいい。 – Lucero

関連する問題