Dictionary containing only Serializable objects

I am looking for a way to ensure that only serializable objects are stored in a dictionary in C #.

To be more specific, I am looking for something similar to this:

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

The problem is that I cannot store primitive types such as integers, booleans or strings.

Is there a way to ensure that my dictionary contains only objects that can be serialized?

+6
source share
5 answers

I do not think you can do this at compile time, but you can do it at runtime. If you build your own class from Dictionary<TKey, TValue> , then in the constructor of your class you can check the attributes attached to the TValue type and make sure that SerializableAttribute is one of them, otherwise throw an exception.

All standard primitive types ( int , bool , etc.) have this attribute.

+4
source

Keep in mind that in classes that are serializable, SerializableAttribute is labeled as opposed to an interface implementation. From MSDN :

Any class that can be serialized must be marked SerializableAttribute. If a class needs to control its serialization process, it can implement the ISerializable interface.

What you need to do is make your own class that implements the IDictioanry interface, and every time someone calls, use a reflex to check if the passed item has a serializable attribute (and throws an exception if it fails).

The code would look like

 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(); } } ..... } 
+2
source
 [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
source

One answer is to create a SerializablePrimative wrapper class.

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

The rest remains as an exercise for the reader, but basically you create an adapter so that these specific types "match" your vocabulary.

* See also: Types Supported by Data Contract Serializer

** See also: C #: Using Reflection to create a new class in .NET

+1
source

How about packing your vocabulary?

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

This way you can be sure that only ISERializable objects and primitive types can be added.

0
source

Source: https://habr.com/ru/post/894915/


All Articles