2011-08-12 13 views
6

मैं यह सुनिश्चित करने के लिए एक तरीका ढूंढ रहा हूं कि सीरियलज़ेबल ऑब्जेक्ट्स सी # में एक शब्दकोश में संग्रहीत हैं।शब्दकोश केवल सीरियलज़ेबल ऑब्जेक्ट्स के साथ युक्त

अधिक विशिष्ट होना करने के लिए मैं इस के समान कुछ करने के लिए देख रहा हूँ:

Dictionary<String, ISerializable> serialDict = new Dictionary<String, ISerializable>(); 

इस के साथ समस्या यह है कि मैं पूर्णांकों, बूलियन्स, या तार की तरह आदिम प्रकार की दुकान नहीं कर सकते हैं।

क्या यह सुनिश्चित करने का कोई तरीका है कि मेरे शब्दकोश में केवल ऑब्जेक्ट्स हैं जिन्हें क्रमबद्ध किया जा सकता है?

उत्तर

4

मुझे नहीं लगता कि आप इसे संकलित समय पर कर सकते हैं, लेकिन आप इसे रनटाइम पर कर सकते हैं। यदि आप Dictionary<TKey, TValue> से प्राप्त अपनी कक्षा बनाते हैं, तो अपनी कक्षा के निर्माता में, आप TValue प्रकार से जुड़े विशेषताओं की जांच कर सकते हैं, और सुनिश्चित करें कि SerializableAttribute उनमें से एक है, और कोई अपवाद फेंक दें।

सभी मानक आदिम प्रकार (int, bool, आदि) में यह विशेषता है।

+0

अंतर्दृष्टि के लिए धन्यवाद, यह अधिक समझ में आता है। मैं एक संकलन समय समाधान की उम्मीद कर रहा था लेकिन यह ठीक काम करेगा। – LamdaComplex

0

अपने शब्दकोश को लपेटने के बारे में क्या?

class SomeClass { 

    Dictionary<string,object> d; 
    // add ISerializable 
    public void Add(string key, ISerializable value) { 
     d[key] = value; 
    } 
    // add primitive types 
    public void Add(string key, bool value) { 
     d[key] = value; 
    } 
    public void Add(string key, int value) { 
     d[key] = value; 
    } 
    // etc ... 
} 

इस तरह से आप सुनिश्चित हैं कि केवल ISerializable ऑब्जेक्ट्स और आदिम प्रकार जोड़े जा सकते हैं। विचार करने के लिए

+1

प्रति एमएसडीएन दस्तावेज, ऑब्जेक्ट्स को केवल सीरियलाइज़ेशन प्रक्रिया को नियंत्रित करने के लिए आईएसरियलज़ेबल इंटरफ़ेस को लागू करने की आवश्यकता होती है। इसलिए कोई भी धारावाहिक वस्तुएं इस इंटरफ़ेस को लागू नहीं करती हैं। – R0MANARMY

1
[Serializable] 
public class SerializableDictionary<TKey, TValue> : Dictionary<TKey, TValue> 
{ 
    static SerializableDictionary() 
    { 
     AssertSerializable(typeof(TKey)); 
     AssertSerializable(typeof(TValue)); 
    } 

    static void AssertSerializable(Type t) 
    { 
     if (!t.IsSerializable) 
     { 
      throw new NotSupportedException(string.Format(
       "{0} is not serializable", t.Name)); 
     } 
    } 
} 
+1

यदि कोई इस शब्दकोश में इनट्स, बूलियन और तारों को स्टोर करना चाहता था, तो टीवीएयू के रूप में किस प्रकार का चयन किया जाना चाहिए? –

+0

@ डेविड अच्छा बिंदु, +1। यह समर्थित नहीं है। लेकिन मैंने सवाल पढ़ा जैसे कि पूछताछ इन प्रकारों में से एक को स्टोर करना चाहता था, न कि उनके संयोजन। –

2

एक बात है कि कक्षाओं कि serializable हैं SerializableAttribute के साथ टैग कर रहे हैं के रूप में एक अंतरफलक को लागू करने का विरोध किया है। MSDN से:

किसी भी वर्ग है कि धारावाहिक की जा सकती है SerializableAttribute के साथ चिह्नित किया जाना चाहिए। यदि किसी वर्ग को अपनी धारावाहिकता प्रक्रिया को नियंत्रित करने की आवश्यकता है, तो यह ISERializable इंटरफ़ेस को कार्यान्वित कर सकता है।

आपको बस इतना करना है अगर यह नहीं करता है (अपने स्वयं के वर्ग है कि अगर तत्व में पारित एक serializable विशेषता है की जाँच करने के IDictioanry इंटरफेस और हर बार किसी को जोड़ने कहता है, उपयोग प्रतिबिंब लागू करता है बनाने के लिए और एक अपवाद फेंक रहा है की आवश्यकता होगी क्या 'टी)।

कोड की तरह

class MyDictionary<TKey, TValue> : IDictionary<TKey, TValue> 
{ 
    private Dictionary<TKey, TValue> d; 

    public void Add(TKey key, TValue value) 
    { 
     if(value.GetType().IsSerializable) 
     { 
      d.Add(key, value); 
     } 
     else 
     { 
      throw new ArgumentException(); 
     } 
    } 
    ..... 
} 
+0

मुझे यह समाधान भी पसंद है, यह सिर्फ मेरी परियोजना के लिए जरूरी चीज है। धन्यवाद। – LamdaComplex

1

एक जवाब कुछ इस प्रकार दिखाई एक SerializablePrimative आवरण वर्ग बनाने के लिए होगी।

class SerializablePrimative<T> : ISerializable { 
    private T val = default(); 

    private SerializablePrimative(T newVal){ 
     val = newVal; 
    } 

    public static boolean IsSupported(Object o){ 
     if (o == null){ 
      return false; 
     }else{ 
      return IsSupported(o.GetType()); 
     } 
    } 

    public static boolean IsSupported(Type t){ 
     if (// you want to support* ...) 
     { 
      return true; 
     } 
     else 
     { 
     return false; 
     } 
    } 

    public static SerializablePrimative GetSerializable(Object o){ 
     if (IsSupported(o)){ 
      return //Intstatiate via Reflection ** 
     }else { 
      return null; 
     } 
    } 
} 

बाकी पाठक के लिए एक व्यायाम के रूप में छोड़ दिया जाता है, लेकिन मूल रूप से अपने इन कुछ प्रकार बनाने के लिए एक एडाप्टर बनाने अपने शब्दकोश "फिट"।

* इन्हें भी देखें: Types Supported by the Data Contract Serializer

** इन्हें भी देखें: C#: Using Reflection to Instantiate a Generic Class in .Net

+0

ऐसा लगता है कि धारावाहिक वर्गों (प्राइमेटिव सहित) को ओवरकिल दिया गया है, पहले ही उपयुक्त विशेषता के साथ टैग किया गया है। – R0MANARMY

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