2009-09-02 6 views
3

辞書から派生したクラスがあります。 SilverlightはHashSetを知らず、クラスはHashSetを大量に使用するため、このクラスがHashSetをシミュレートするために必要です。そこで私はHashSetをDictionaryと交換することに決めました。辞書から派生したクラスに対してforeachを有効にする

class HashSet<T> : Dictionary<T, object> 
{ 

    public override void Add(T element) 
    { 
     base.Add(element, null); 
    } 
} 

は、今私は有効にする必要があります。さらに、すべてのHashSet、オブジェクトの私のクラスを使用するには、私は、それが辞書から派生したカスタムHashSetのクラスを作成し、Add-法のようなすべてのrelavantメソッドをオーバーライドしてみてください私の新しいHashSetクラスのforeach-loopです。明らかに、私のクラスはforeachループでKeyValuePairを返しますが、戻り値の型としてTが必要です。誰でも私に教えてください、どのように私はディクショナリの基本クラスをオーバーライドする必要がありますか?事前に

おかげで、 フランク

+0

本当に良い質問です。 Jon Skeetの答えは私のコードベースが私たちの立場からはるかに意味を持ち、使いやすくするのに役立ちます。 –

答えて

15

は、私は強くあなたがいないが最初の場所でDictionaryから派生しないことを示唆しています。継承の代わりに合成を使用する。 Dictionaryから派生した場合、人々はあなたのクラスを、セットではなくキー/値ペアの辞書として使用できます。

だから、あなたはその中の辞書を使ってクラスを設計します

public sealed class DictionaryBackedSet<T> : IEnumerable<T> 
{ 
    private readonly Dictionary<T, int> dictionary = new Dictionary<T, int>(); 

    public IEnumerator<T> GetEnumerator() 
    { 
     return dictionary.Keys.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public bool Add(T item) 
    { 
     if (Contains(item)) 
     { 
      return false; 
     } 
     dictionary.Add(item, 0); 
     return true; 
    } 

    public bool Contains(T item) 
    { 
     return dictionary.ContainsKey(item); 
    } 

    // etc 
} 

ます。また、辞書の値の型引数として空の構造体を作成することがあります:

public struct Empty {} 

5月少しのメモリを節約する。でも、私は今のところ心配はない - あなたはそれからを継承辞書代わりにを構成場合は、後でその変更を行うことは何も中断されません:)

あなたが使用できるならば、それはいいだろうこの目的のためにSystem.Void(すなわちDictionary<T, Void>を使用)が、C#が、私はあなたが内部キーコレクションで作業思われる、(Tの)のIEnumerableを実装する必要があるでしょうだと思う

+0

Empty構造体を使用していない場合、この例ではbit over intを使用するべきではありませんか? – stevehipwell

+0

ありがとうJon!私はあなたの提案に従い、継承の代わりに合成を使用します。 foreachを有効にするには、2つのGetEnumeratorメソッドで十分ですか?私は(少なくとも)現在、MoveNextとリセットを実装する必要があると思った。 – Aaginor

+0

@aaginor:それは 'IEnumerator'を実装するでしょう。ディクショナリ自体から返されたキーのシーケンスを使用できるため、これを行う必要はありません。あなただけのピギーバックです。 –

2

:(ことをあなたが行うことはできません。

IDictionaryはすでにIEnを実装していますumerable(Of KeyValuePair(Of TKey、TValue)))、おそらくそれを別の型に対しても実装することは可能でしょうか?

私はJonと再サブクラスをしようとしています - 可能ならば避けてください、構図ははるかに適切なデザインパターンです。

+1

Keyコレクションで、Valuesコレクションではありません。 Valuesコレクションはすべてnull(または0など)になります。 –

+0

彼のコードで編集され、完全に逃した。 – richardtallent

3

辞書から継承するのではなく、それをラップすることをお勧めします。 HashSetは辞書ではありません。

関連する問題