2015-11-11 73 views
7

集合的參考我有幾個字典:獲取給定類型

Dictionary<int, Type1> Type1Dictionary { get; set; } 
Dictionary<int, Type2> Type2Dictionary { get; set; } 
Dictionary<int, Type3> Type3Dictionary { get; set; } 
Dictionary<int, Type4> Type4Dictionary { get; set; } 

Typei (i = 1..4)是從同一個基類(BaseType)的。我想要一個方法返回給定類型的字典的引用。後來,我將執行一些操作,如添加或者在字典中移除:

​​

注:我不想把我的詞典爲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) { /*...*/ } 
} 

編輯:

我真正想要的是避免以下結構:

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'出現在同一個字典中。但爲了刪除或添加一個對象,我真的不在乎字典是如何處理的(如果它是正確的類型)。我寫的代碼並沒有解決我的問題,順便說一句。 – Sturm

+0

聽起來像訪問者模式的候選人,或者使用'dynamic'並將問題移到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)'只有一個字典,儘管這並不是問題中的問題。 –

0

的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 
{ 
} 

移動的東西到DLR都有自己的缺陷(即什麼是編譯時間問題,現在運行時的問題),所以這需要審查。這只是一種方法。另一種方法是實現訪問者模式。另一種方法是你目前得到的。

不要把這個答案辦法做到這一點。