The problem: I have Dictionary<String, String>
that I need an alias to, but I also need to serialize/deserialize it.
Solutions I've tried:
class Foo : Dictionary<String, String> { }
but that work because I would have to create a Deserialization constructor and that would be a bit silly when Dictionary already can be deserialized.
I also tried
using Foo = System.Collections.Generic.Dictionary<String, String>;
but I need this to work in more that one file and if add that line in all the files that need it, I'll be removing half the point of typedefs (that is, if I need to change the type, I can do so easily)
What can I do about this?
With the alias approach attributes are preserved, but you state that is too much overhead (per-file etc).
Type-level attributes are genercally preserved - but it depends on the attribute - for [Serializable]
, note that it has:
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct
| AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false)]
the Inherited = false
being significant - i.e. it is not inherited.
Personally I probably would have focused on getting the serialization ctor/callbacks working in the first example - I doubt it would have needed much more effort. The following seems 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 via 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();
}
}
Mmm "that would be a bit silly when Dictionary already can be deserialized." I wouldn't say it's silly to call a base ctor in (almost) any case + it's 1 min effort, so I'd 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)
{
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With