2015-11-11 4 views
7

私はいくつかの辞書を持って指定されたコレクションの参照を取得します。私は、型を与えられた辞書の参照を返すメソッドが必要です。追加またはその辞書に削除するようにその後、私はいくつかの操作を実行します:タイプ

​​

注:私はこのような何かを書くことができDictionary<int, BaseType>

としての私の辞書を設定したくないことはないだろう辞書への参照を返す:

Dictionary<int, BaseType> GetDictionary(BaseType myObject) 
{ 
    var dic = new Dictionary<int, BaseType>(); 
    if(myObject is Type1) 
    { 
    //ideally I would return my Type1Dictionary here but I can't due type incompatibility 
     foreach(var x in Type1Dictionary) 
     { 
      dic.Add(x.Key, x.Value); 
     } 
     return dic; 
    } 
    if(myObject is Type2) { /*...*/ } 
    if(myObject is Type3) { /*...*/ } 
    if(myObject is Type4) { /*...*/ } 
} 

EDIT:

私が本当にしたいことは、次の構造を避けるためです:

AddObject(BaseType x) 
{ 
    Type1 x1 = x as Type1; 
    if(x1 != null) { Type1Dictionary.Add(x1.ID, x1); } 

    Type2 x2 = x as Type2; 
    if(x2 != null) { Type2Dictionary.Add(x2.ID, x2); } 

    Type3 x3 = x as Type3; 
    if(x3 != null) { Type3Dictionary.Add(x3.ID, x3); } 

    Type4 x4 = x as Type4; 
    if(x4 != null) { Type4Dictionary.Add(x4.ID, x4); } 
} 

RemoveObject(BaseType x) 
{ 
    Type1 x1 = x as Type1; 
    if(x1 != null) { Type1Dictionary.Remove(x1.ID); } 

    Type2 x2 = x as Type2; 
    if(x2 != null) { Type2Dictionary.Remove(x2.ID); } 

    Type3 x3 = x as Type3; 
    if(x3 != null) { Type3Dictionary.Remove(x3.ID); } 

    Type4 x4 = x as Type4; 
    if(x4 != null) { Type4Dictionary.Remove(x4.ID); } 
} 

しかし、その代わりに:

AddObject(BaseType x) 
{ 
    var dic = GetDictionary(x); 
    dic.Add(x.ID, x); 
} 

RemoveObject(BaseType x) 
{ 
    var dic = GetDictionary(x); 
    dic.Remove(x.ID); 
} 
+1

'int'から' BaseType'にマップする辞書は必要ありませんが、同じことをする辞書を返しますか? –

+0

私は 'Type2'オブジェクトが' Type1'と同じ辞書に入ることを望ましくありません。しかし、オブジェクトを削除または追加するためには、辞書がどのように扱われているかは気にしません(正しいタイプの場合)。私が書いたコードは私の問題を解決しません、btw。 – Sturm

+0

訪問者パターンの候補のように聞こえますが、「ダイナミック」を使用して問題をDLRに移動してください。 –

答えて

5

をこれがthead要素、安全性などの面で研磨することができる。しかし、あなたが基本的なアイデアを得ることができる必要があります:

public interface IEntity 
{ 
    int ID { get; } 
} 

public class Superset<T> where T : IEntity 
{ 
    public Dictionary<Type, Dictionary<int, T>> m_Map = 
    new Dictionary<Type, Dictionary<int, T>>(); 

    private Dictionary<int, T> GetDictionary(Type t) 
    { 
    Dictionary<int, T> result = null; 
    if (!m_Map.TryGetValue(t, out result)) 
    { 
     result = new Dictionary<int, T>(); 
     m_Map.Add(t, result); 
    } 
    return result; 
    } 

    public void Add<K>(K item) where K : T 
    { 
    GetDictionary(typeof(K)).Add(item.ID, item); 
    } 

    public bool Remove<K>(K item) where K : T 
    { 
    return GetDictionary(typeof(K)).Remove(item.ID); 
    } 
} 
+0

この解決法は依然として基本型の辞書を作成するだけで、それぞれの 'typeof(K)'に対して1つのみを作成するということは追加する価値はあるが、これは質問には問題として述べられていない。 –

0

DLRダイナミックなディスパッチというこれらのトリックを演奏することができます。実行時に必要なメソッドを解決します。これにより、強力な型の多くの辞書を持つことができますが、より一般化された処理メカニズムです。私は、共通のイベントベースから来るイベントを処理するためにこれを行います。 DLRにものを移動

class Program 
{ 
    private static Dictionary<int, Foo> _foos = new Dictionary<int, Foo>(); 
    private static Dictionary<int, Baz> _bazs = new Dictionary<int, Baz>(); 

    static void Main(string[] args) 
    { 
     Bar foo = new Foo(); 
     Bar baz = new Baz(); 

     Add(foo); // Resolves at runtime to Add(Foo f) 
     Add(baz); // Resolves at runtime to Add(Baz b) 
    } 

    public static void Add(Bar b) 
    { 
     Add((dynamic)b); 
    } 

    private static void Add(Foo f) 
    { 
     _foos.Add(1, f); 
    } 

    private static void Add(Baz b) 
    { 
     _bazs.Add(1, b); 
    } 
} 

class Foo : Bar 
{ 
} 

class Baz : Bar 
{ 
} 

class Bar 
{ 
} 

は、独自の落とし穴が付属しています(コンパイル時の問題だったつまり今何ランタイム問題となっている)ので、これは見直しが必要です。それは単なる1つのアプローチです。もう1つのアプローチはビジターパターンの実装です。もう一つのアプローチはあなたが現在持っているものです。

この回答をとしてください。