Serializing the dictionary <string, object> when the dictionary was initialized using string-insensitive string comparison
I am serializing a dictionary in XML. When I create a new dictionary, I use the constructor to provide EqualityComparer without a shell, for example
var tabs = new Dictionary<string,Tab>(StringComparer.OrdinalIgnoreCase); Then I serialize to XML and when I deserialize the casing information, it is lost - deserialization is done using a dictionary with the GenericEqualityComparer, which seems to be case sensitive because it does not find my keys if they are not set correctly.
Any ideas how I can change it?
One way is to create a new dictionary and copy the data from deserialized to a new one, but it seems unpleasant.
UPDATE:
Deserialization worked all the time, until it simply deserializes a serialized dictionary that does not use case-insensitive keys.
I know this question is pretty old, but recently I found how to do it.
Using .Net4 (e.g. @mare said), you can create some really nice extension methods to make this easy. Check out fooobar.com/questions/76824 / ... for a nice and simple implementation.
After a lot of digging, it worked like a charm for me.
Edit:
In the comments, it looks like this approach may be deprecated in .NET 4.
Edit end
Dictionaries happen to require a little help for serialization and deserialization.
Here is a good example of an XML Serializable dictionary:
http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx
You can make case insensitive by changing the class declaration and adding a constructor and changing the string.
** EDIT: Fixed syntax error below. / EDIT **
public class SerializableDictionary<TValue> : Dictionary<string, TValue>, IXmlSerializable { public SerializableDictionary() : base(StringComparer.InvariantCultureIgnoreCase) { } // ... } Change the line this.Add(key, value); on this[key] = value; .
In any case, you may need a ton of some details, but this should help you well.
You just need to wrap your new dictionary in the constructor:
Dictionary<string, Tab> tabs ; tabs = new Dictionary<string, Tab>((Dictionary<string, Tab>)serializer.ReadObject(reader),StringComparer.OrdinalIgnoreCase); An old question that I understand, but just broke through the source to Dictionary and noticed that it should actually serialize Comparer:
info.AddValue(ComparerName, comparer, typeof(IEqualityComparer<tkey>)); Then, in the implementation of IDeserializationCallback.OnDeserialization it retrieves Comparar:
comparer = (IEqualityComparer<tkey>)m_siInfo.GetValue(ComparerName, typeof(IEqualityComparer<tkey>)); Classes that implement the IDeserializationCallback interface define the method that must be executed after the instance has been deserialized, but before it is returned to your code.
Reference: Dictionary.cs GetObjectData and OnDeserialization Methods