2015-11-11 21 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) से हुआ है। मुझे एक ऐसी विधि चाहिए जो एक प्रकार के शब्दकोश के संदर्भ को वापस करे। बाद में, मैं कुछ कार्रवाई करने की तरह जोड़ें या कि शब्दकोश पर निकालें:

Type1 example = new Type1(); 
var dic = GetDictionary(example); 
dic.Add(example.ID, example); 

नोट्स: मैं अपने शब्दकोशों स्थापित करने के लिए के रूप में 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' से' बेसटाइप 'के नक्शे पर है, लेकिन आप एक शब्दकोश वापस करते हैं जो वही काम करता है? –

+0

मैं 'टाइप 2' ऑब्जेक्ट्स को 'टाइप 1' के समान शब्दकोष में नहीं देना चाहता हूं। लेकिन किसी ऑब्जेक्ट को हटाने या जोड़ने के लिए मुझे वास्तव में परवाह नहीं है कि शब्दकोश का इलाज कैसे किया जाता है (यदि यह सही प्रकार का है)। मैंने जो कोड लिखा है वह मेरी समस्या को हल नहीं करता है, बीटीडब्ल्यू। – Sturm

+0

विज़िटर पैटर्न के लिए उम्मीदवार की तरह लगता है, या 'गतिशील' का उपयोग करें और समस्या को डीएलआर में ले जाएं। –

उत्तर

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

यह जोड़ना उचित है कि यह समाधान अभी भी बेस टाइप का एक शब्दकोश बनाता है, केवल प्रत्येक 'टाइपफ़ोफ़ (के)' के लिए एक है, हालांकि इसे प्रश्न में कोई समस्या नहीं कहा गया है। –

0

डीएलआर इन चालें खेल सकते हैं: गतिशील प्रेषण। यह रनटाइम पर आवश्यक विधि को हल करता है। यह आपको मजबूत प्रकार के कई शब्दकोशों की अनुमति देता है, लेकिन एक अधिक सामान्यीकृत हैंडलिंग तंत्र। मैं ऐसा घटनाओं को संभालने के लिए करता हूं जो एक आम घटना आधार से आते हैं।

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

डीएलआर में जा सामान अपने स्वयं के नुकसान (अर्थात् क्या संकलन समय समस्याओं अब समस्याओं क्रम रहे थे) के साथ आता है, तो यह समीक्षा करने की जरूरत है। यह सिर्फ एक दृष्टिकोण है। एक और दृष्टिकोण आगंतुक पैटर्न का कार्यान्वयन है। एक और दृष्टिकोण वह है जिसे आपने वर्तमान में प्राप्त किया है।

इसे करने के लिए इस उत्तर को न लें।

संबंधित मुद्दे