I’m trying to serialize a Hashset but I’m having no luck. Whenever I try to open the serialized data, I get an empty HashSet. However, a List works fine. Example code:
[Serializable()]
public class MyClass : ISerializable
{
public MyClass(SerializationInfo info, StreamingContext ctxt)
{
HashSet<string> hashset = (HashSet<string>)info.GetValue("hashset", typeof(HashSet<string>));
List<string> list = (List<string>)info.GetValue("list", typeof(List<string>));
Console.WriteLine("Printing Hashset:");
foreach (string line in hashset)
{
Console.WriteLine(line);
}
Console.WriteLine("Printing List:");
foreach (string line in list)
{
Console.WriteLine(line);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
{
HashSet<string> hashset = new HashSet<string>();
hashset.Add("One");
hashset.Add("Two");
hashset.Add("Three");
info.AddValue("hashset", hashset);
List<string> list = new List<string>();
list.Add("One");
list.Add("Two");
list.Add("Three");
info.AddValue("list", list);
}
}
And when run, it prints out:
Printing Hashset:
Printing List:
One
Two
Three
So the List works fine, but the HashSet comes back empty. A little stuck – can anyone see what I’m doing wrong? Thanks
Update:
As Hans Passant stated there are simple workaround, just call HashSet.OnDeserialization manually.
It also helps with other Generic collections.
As far as I can see this is probably bug in
HashSet<T>implementation.HashSetcorrectly serialized intoSerializationInfo:and
SerializationInfocorrectly restored. You can check also by yourself, take a look to:(((System.Collections.Generic.HashSet<string>)(info.m_data[0]))).m_siInfo.m_data[3]but fails to restore its state:All it do is simply stores
SerializationInfo:You can check
(hashset).m_siInfo.MemberValues[3], values was correcly restored by formatter but not “interpreted” byHashSet.Similar problem has
Dictionary<TKey,TValue>or e.g.LinkedList<T>.List<T>(or similar array based collections such asStack<T>) has no problem since they serialized as array (without special logic).IMHO,
BinaryFormatteris not really good and efficient way to store values. You can try to use DataContractSerializer (it can handle such types) or go with serialization helpers such as protobuf.net, json.net etc. See Why is binary serialization faster than xml serialization? and Performance Tests of Serializations used by WCF Bindings