Обновление
Как Ганс Пассант заявил есть простой обходной путь, просто вызовите HashSet.OnDeserialization вручную.
var hashset = (HashSet<string>)info.GetValue("hashset", typeof(HashSet<string>));
hashset.OnDeserialization(this);
Это также помогает с другими универсальными коллекциями.
Насколько я понимаю, это, вероятно, ошибка в реализации HashSet<T>
. HashSet
правильно сериализовано в SerializationInfo
:
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("Version", this.m_version);
info.AddValue("Comparer", this.m_comparer, typeof(IEqualityComparer<T>));
info.AddValue("Capacity", (this.m_buckets == null) ? 0 : this.m_buckets.Length);
if (this.m_buckets != null)
{
T[] array = new T[this.m_count];
this.CopyTo(array);
info.AddValue("Elements", array, typeof(T[]));
}
}
и SerializationInfo
правильно восстановлены. Вы также можете проверить сами, посмотрите: (((System.Collections.Generic.HashSet<string>)(info.m_data[0]))).m_siInfo.m_data[3]
, но не можете восстановить его состояние:
Все, что он делает, это просто хранит SerializationInfo
:
protected HashSet(SerializationInfo info, StreamingContext context)
{
this.m_siInfo = info;
}
Вы можете проверить (hashset).m_siInfo.MemberValues[3]
, значения были правильно восстановлены форматером, но не "интерпретированы" HashSet
.
Аналогичная проблема имеет Dictionary<TKey,TValue>
или, например, LinkedList<T>
.
List<T>
(или аналогичные коллекции на основе массива, такие как Stack<T>
) не имеют проблем, поскольку они сериализованы как массив (без специальной логики).
Обходной путь был опубликован Хансом Пассантом.
ИМХО, BinaryFormatter
не очень хороший и эффективный способ хранения значений. Вы можете попробовать использовать DataContractSerializer (он может обрабатывать такие типы) или использовать помощники по сериализации, такие как protobuf.net, json.net и т. Д. См. Почему двоичная сериализация быстрее, чем сериализация xml? и Тесты производительности сериализаций, используемые привязками WCF