C # Typedef that stores attributes

Problem: I have a Dictionary<String, String> that I need an alias for, but I also need to serialize / deserialize it.

The solutions I tried:

 class Foo : Dictionary<String, String> { } 

but it works because I would have to create a deserialization constructor, and that would be a little silly if the dictionary can already be deserialized.

I also tried

 using Foo = System.Collections.Generic.Dictionary<String, String>; 

but I need this to work in more than one file, and if I add this line to all the files that need it, I will remove half the point of typedefs (that is, if I need to change the type, I can do it easily)

What can i do with this?

+6
c # alias serialization typedef
source share
2 answers

When using the attributes of the approach, aliases are preserved, but you indicate that there are too many auxiliary ones (per-file, etc.).

Level-level attributes are usually stored - but it depends on the attribute - for [Serializable] , note that it has:

 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)] 

Inherited = false is significant - that is, it is not inherited.

Personally, I would probably focus on making the ctor / callbacks serialization work in the first example - I doubt it would take much more effort. The following looks fine:

 [Serializable] public class Foo: Dictionary<string, string> { public Foo() : base() { } public Foo(SerializationInfo info, StreamingContext context) : base(info, context) { } public Foo(int capacity) : base(capacity) { } public Foo(IEqualityComparer<string> comparer): base(comparer) {} public Foo(IDictionary<string,string> dictionary) : base(dictionary) { } public Foo(int capacity, IEqualityComparer<string> comparer) : base(capacity, comparer) { } public Foo(IDictionary<string, string> dictionary, IEqualityComparer<string> comparer) : base(dictionary, comparer) { } } 

However, here's an alternative through encapsulation:

 [Serializable] public class Foo : IDictionary<string,string> { private readonly Dictionary<string, string> inner = new Dictionary<string, string>(); public void Add(string key, string value) { inner.Add(key, value); } public bool ContainsKey(string key) { return inner.ContainsKey(key); } public ICollection<string> Keys { get { return inner.Keys; } } public bool Remove(string key) { return inner.Remove(key); } public bool TryGetValue(string key, out string value) { return inner.TryGetValue(key, out value); } public ICollection<string> Values { get { return inner.Values; } } public string this[string key] { get { return inner[key]; } set { inner[key] = value; } } void ICollection<KeyValuePair<string, string>>.Add(KeyValuePair<string, string> item) { ((IDictionary<string,string>)inner).Add(item); } public void Clear() { inner.Clear(); } bool ICollection<KeyValuePair<string, string>>.Contains(KeyValuePair<string, string> item) { return ((IDictionary<string, string>)inner).Contains(item); } void ICollection<KeyValuePair<string, string>>.CopyTo(KeyValuePair<string, string>[] array, int arrayIndex) { ((IDictionary<string, string>)inner).CopyTo(array, arrayIndex); } public int Count { get { return inner.Count; } } bool ICollection<KeyValuePair<string, string>>.IsReadOnly { get { return ((IDictionary<string, string>)inner).IsReadOnly; } } bool ICollection<KeyValuePair<string, string>>.Remove(KeyValuePair<string, string> item) { return ((IDictionary<string, string>)inner).Remove(item); } public IEnumerator<KeyValuePair<string, string>> GetEnumerator() { return inner.GetEnumerator(); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return inner.GetEnumerator(); } } 
+6
source share

Mmm, "that would be a little silly if the dictionary can already be deserialized." I would not say that it is foolish to call the base ctor in (almost) anyway + this is 1 min, so I would say do it ...

 [Serializable] public class Foo : Dictionary<string, string> { public Foo() : base() { } public Foo(SerializationInfo info, StreamingContext context) : base(info, context) { } } 

or

 [Serializable] public class Foo<TKey,TValue> : Dictionary<TKey,TValue> { public Foo() : base() { } public Foo(SerializationInfo info, StreamingContext context) : base(info, context) { } } 
+1
source share

All Articles