2016-02-07 2 views
1

У меня проблемы с дезактивацией/сериализации словаря, работающего при реализации ISerializable в охватывающем классе. Кажется, он может автоматически дезактивировать/сериализовать, если я просто применил SerializableAttribute. Однако мне нужно проверить десериализованный словарь в этом процессе, поэтому мне нужно, чтобы ISerializable работал.Deserializing .NET Dictionary с использованием ISerializable

Я установил небольшой тест, чтобы быть уверенным, что это не было связано с некоторыми другими проблемами. Test класса выглядит следующим образом:

[Serializable] 
class Test : ISerializable 
{ 
    private Dictionary<string, int> _dict; 

    public Test() 
    { 
     var r = new Random(); 
     _dict = new Dictionary<string, int>() 
     { 
      { "one", r.Next(10) }, 
      { "two", r.Next(10) }, 
      { "thr", r.Next(10) }, 
      { "fou", r.Next(10) }, 
      { "fiv", r.Next(10) } 
     }; 
    } 

    protected Test(SerializationInfo info, StreamingContext context) 
    { 
     // Here _dict.Count == 0 
     // So it found a Dictionary but no content? 
     _dict = (Dictionary<string, int>)info.GetValue("foo", typeof(Dictionary<string, int>)); 
    } 

    public void GetObjectData(SerializationInfo info, StreamingContext context) 
    { 
     info.AddValue("foo", _dict, typeof(Dictionary<string, int>)); 
    } 

    public override string ToString() 
    { 
     var sb = new StringBuilder(); 
     foreach (var pair in _dict) 
      sb.Append(pair.Key).Append(" : ").Append(pair.Value).AppendLine(); 
     return sb.ToString(); 
    } 
} 

И главного проверить:

static void Main(string[] args) 
{ 
    var t1 = new Test(); 
    Console.WriteLine(t1); 
    var formatter = new BinaryFormatter(); 
    using (var stream = new FileStream("test.test", FileMode.Create, FileAccess.Write, FileShare.None)) 
     formatter.Serialize(stream, t1); 

    Test t2; 
    using (var stream = new FileStream("test.test", FileMode.Open, FileAccess.Read, FileShare.Read)) 
     t2 = (Test)formatter.Deserialize(stream); 
    Console.WriteLine(t2); 
    Console.ReadLine(); 
} 

выхода в консоли то же самое до и после. Но как указано в классе Test, перегруженный конструктор не читает никакого содержимого в десериализованном словаре.

Я делаю что-то неправильно или это ошибка/тонкий побочный эффект?

+0

Моя проблема не в том, можно ли сериализовать или нет, но как «взять под контроль» процесс сериализации, если вы захотите (используя реализацию ISerializable), whi ch, кажется, терпит неудачу. – Xerillio

+0

@OrelEraki: OP задает вопрос о двоичной сериализации и, в частности, о действительности десериализованного экземпляра. Предоставленные ссылки не затрагивают эту конкретную область. – alexm

+0

@OrelEraki: Я просмотрел ответы. Ответы во второй ссылке не затрагивают двоичную сериализацию словаря как члена составного объекта, что является сущностью этого вопроса. – alexm

ответ

1

Dictionary<TKey, TValue> выполняет IDeserializationCallback и откладывает завершение де-сериализации до тех пор, пока весь график объектов не будет считан. Вы можете увидеть, как это было на самом деле реализован на Reference Source:

protected Dictionary(SerializationInfo info, StreamingContext context)    

{ 
    //We can't do anything with the keys and values until the entire graph has been deserialized 
    //and we have a resonable estimate that GetHashCode is not going to fail. For the time being, 
    //we'll just cache this. The graph is not valid until OnDeserialization has been called. 
    HashHelpers.SerializationInfoTable.Add(this, info); 
} 

Чтобы заставить завершение вызова _dict.OnDeserialization() в коде:

protected Test(SerializationInfo info, StreamingContext context) 
{ 
    // Here _dict.Count == 0 
    // So it found a Dictionary but no content? 
    _dict = (Dictionary<string, int>)info.GetValue("foo", typeof(Dictionary<string, int>)); 

    _dict.OnDeserialization(null); 

    // Content is restored. 
    Console.WriteLine("_dict.Count={0}", _dict.Count); 
} 

PS: HashSet<T>, SortedSet<T>, LinkedList<T> и, возможно, несколько других типов контейнеров демонстрируют такое же поведение

+0

Отлично, спасибо! Он работает сейчас. Также спасибо за ссылку, о которой не знали. – Xerillio

Смежные вопросы