Десериализация словаря словарей
От: anton_nix Россия http://a-nepomnyaschih.moikrug.ru/
Дата: 08.10.07 06:39
Оценка:
Почему Dictionary десериализуется в последнюю очередь и как с этим бороться? Мне надо сделать словарь, у которого ключ — тоже словарь, а я не могу его десериализовать

При десериализации в конструкторе MyDictionary извлекаемые MyKey пустые! И заполняются только уже после всей десериализации! Вот и вылетает исключение, что такой элемень уже добавлен в словарь! Как же это тогда десериализовать?!

        [Serializable]
        class MyKey : Dictionary<int, int>
        {
            public MyKey(params int[] nums)
            {
                foreach (int i in nums)
                {
                    Add(i, 0);
                }
            }

            protected MyKey(SerializationInfo info, StreamingContext context) : base(info, context)
            {
                
            }
            public override bool Equals(object obj)
            {
                if (obj == null || GetType() != obj.GetType())
                {
                    return false;
                }
                MyKey key = (MyKey)obj;
                if (key.Count != Count)
                {
                    return false;
                }
                Enumerator enumerator1 = GetEnumerator();
                Enumerator enumerator2 = key.GetEnumerator();
                while (enumerator1.MoveNext())
                {
                    enumerator2.MoveNext();
                    if (!enumerator1.Current.Key.Equals(enumerator2.Current.Key) ||
                        !enumerator1.Current.Value.Equals(enumerator2.Current.Value))
                    {
                        return false;
                    }
                }
                return true;
            }

            public override int GetHashCode()
            {
                int hash = 0;
                foreach (KeyValuePair<int, int> pair in this)
                {
                    hash ^= pair.Key ^ pair.Value;
                }
                return hash;
            }
        }

        [Serializable]
        class MyDictionary : Dictionary<MyKey, int>
        {
            public MyDictionary()
            {
            }

            protected MyDictionary(SerializationInfo info, StreamingContext context)
            {
                int count = info.GetInt32("count");
                for (int i = 0; i < count; ++i)
                {
                    MyKey key = (MyKey)info.GetValue(i + "key", typeof(MyKey));
                    int value = info.GetInt32(i + "value");
                    Add(key, value);
                }
            }

            public override void GetObjectData(SerializationInfo info, StreamingContext context)
            {
                int i = 0;
                foreach (KeyValuePair<MyKey, int> pair in this)
                {
                    info.AddValue(i + "key", pair.Key);
                    info.AddValue(i + "value", pair.Value);
                    ++i;
                }
                info.AddValue("count", i);
            }
        }
        //[Serializable]
        //class MyDictionary : List<MyKey>, ISerializable
        //{
        //    public MyDictionary()
        //    {
        //    }

        //    protected MyDictionary(SerializationInfo info, StreamingContext context)
        //    {
        //        int count = info.GetInt32("count");
        //        for (int i = 0; i < count; ++i)
        //        {
        //            MyKey key = (MyKey)info.GetValue(i.ToString(), typeof(MyKey));                    
        //            if (Contains(key))
        //            {
        //                throw new NotSupportedException();
        //            }
        //            Add(key);
        //        }
        //    }

        //    public void GetObjectData(SerializationInfo info, StreamingContext context)
        //    {
        //        int i = 0;
        //        foreach (MyKey key in this)
        //        {
        //            info.AddValue(i.ToString(), key);                    
        //            ++i;
        //        }
        //        info.AddValue("count", i);
        //    }
        //}

        [Test]
        public void DelayedDeserializationTest()
        {
            MyKey key1 = new MyKey();
            key1.Add(1, 2);
            key1.Add(2, 1);
            MyKey key2 = new MyKey();
            key2.Add(1, 2);
            key2.Add(2, 1);
            Assert.AreEqual(key1, key2);
            key2.Add(3, 2);
            Assert.AreNotEqual(key1, key2);

            MyDictionary dic = new MyDictionary();
            dic.Add(new MyKey(0, 1, 2), 0);
            dic.Add(new MyKey(1, 2, 3), 0);
            dic.Add(new MyKey(2, 3, 4), 0);
            //dic.Add(new MyKey(0, 1, 2));
            //dic.Add(new MyKey(1, 2, 3));
            //dic.Add(new MyKey(2, 3, 4));

            using (FileStream outSteam = new FileStream("1.tmp", FileMode.Create))
            {
                formatter.Serialize(outSteam, dic);
            }

            using (FileStream inStream = new FileStream("1.tmp", FileMode.Open))
            {
                formatter.Deserialize(inStream);
            }
        }
Re: Десериализация словаря словарей
От: Sinclair Россия https://github.com/evilguest/
Дата: 08.10.07 09:52
Оценка: 1 (1)
Здравствуйте, anton_nix, Вы писали:

_>Почему Dictionary десериализуется в последнюю очередь и как с этим бороться? Мне надо сделать словарь, у которого ключ — тоже словарь, а я не могу его десериализовать


_>При десериализации в конструкторе MyDictionary извлекаемые MyKey пустые!

1. А зачем ты взялся делать сериализацию словаря вручную? Стандартная не работает?
2. Если взялся делать сериализацию вручную — надо было идти до конца, т.е. реализовывать конструктор вручную.
3. Если уж совсем не терпится — вызови OnDeserialization у прочитанных из потока MyKey:

protected MyDictionary(SerializationInfo info, StreamingContext context)
{
    int count = info.GetInt32("count");
    for (int i = 0; i < count; ++i)
    {
        MyKey key = (MyKey)info.GetValue(i + "key", typeof(MyKey));
        key.OnDeserialization(this);
        int value = info.GetInt32(i + "value");
        Add(key, value);
    }
}
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Десериализация словаря словарей
От: anton_nix Россия http://a-nepomnyaschih.moikrug.ru/
Дата: 11.10.07 03:10
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, anton_nix, Вы писали:


_>>Почему Dictionary десериализуется в последнюю очередь и как с этим бороться? Мне надо сделать словарь, у которого ключ — тоже словарь, а я не могу его десериализовать


_>>При десериализации в конструкторе MyDictionary извлекаемые MyKey пустые!

S>1. А зачем ты взялся делать сериализацию словаря вручную? Стандартная не работает?
S>2. Если взялся делать сериализацию вручную — надо было идти до конца, т.е. реализовывать конструктор вручную.
Показалось странным, что словарь так странно десериализуется.
S>3. Если уж совсем не терпится — вызови OnDeserialization у прочитанных из потока MyKey:
Интересно, почему десериализация в этом методе?

S>
S>protected MyDictionary(SerializationInfo info, StreamingContext context)
S>{
S>    int count = info.GetInt32("count");
S>    for (int i = 0; i < count; ++i)
S>    {
S>        MyKey key = (MyKey)info.GetValue(i + "key", typeof(MyKey));
S>        key.OnDeserialization(this);
S>        int value = info.GetInt32(i + "value");
S>        Add(key, value);
S>    }
S>}
S>


Огромное спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.