Тип сериализации как словарь - PullRequest
1 голос
/ 15 февраля 2012

Я пытаюсь сериализовать Dictionary<int, int> как Dictionary<string, string>.

Итак, я создал Test2 тип из Dictionary<int, int> следующим образом:

    [Serializable]
    internal sealed class Test2 : Dictionary<int, int>
    {
        internal Test2()
        {
        }

        private Test2(SerializationInfo info, StreamingContext context)
        {
            var data = (Dictionary<string, string>)
                       info.GetValue("data", typeof(Dictionary<string, string>));
            foreach (var item in data)
                Add(int.Parse(item.Key), int.Parse(item.Value));
        }

        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            var data = new Dictionary<string, string>();
            foreach (var item in this)
                data[item.Key.ToString()] = item.Value.ToString();
            info.AddValue("data", data, typeof(Dictionary<string, string>));
        }
    }

и используюследующий код для проверки сериализации:

        var test2 = new Test2 {{10, 10}};
        var formatter = new BinaryFormatter();
        using (var stream = new MemoryStream())
        {
            formatter.Serialize(stream, test2);
            stream.Position = 0;
            var clone = (Test2) formatter.Deserialize(stream);
        }

По какой-то причине клон не содержит никаких данных (Экв. эквалайзера до 0).

Обновление:

«int» и «string» здесь только для тестирования.В реальном приложении я использую что-то вроде Primary Key вместо строки и большого объекта вместо int, и сериализованный массив содержит отношения между ними.Сокращая несвязанный код и заменяя типы, которыми я заканчиваю, на приведенный выше пример.

Я могу использовать только функции .NET Framework.

1 Ответ

0 голосов
/ 15 февраля 2012

Вам не нужно преобразовывать целые числа в строки во время сериализации или определять свой собственный сериализуемый класс - фреймворк позаботится об этом за вас. Этот код (измененный с этот вопрос ) будет делать то, что вы хотите, просто отлично:

var test2 = new Dictionary<int, int> { { 10, 10 } } ;
var formatter = new BinaryFormatter();
using (MemoryStream stream = new MemoryStream())
{
    formatter.Serialize(stream, test2);
    stream.Position = 0;
    var clone = (Dictionary<int, int>) formatter.Deserialize(stream);
}

Я не уверен, почему ваш исходный код не работал, но я думаю, что это как-то связано с тем, что коллекция SerializationInfo не может правильно сериализовать / десериализовать словари. Я заменил ваш класс этим кодом, который использует List<Tuple<string,string>> вместо Dictionary<string,string>, и он отлично работает:

[Serializable]
internal sealed class Test2 : Dictionary<int, int>
{
    internal Test2()
    {
    }

    private Test2(SerializationInfo info, StreamingContext context)
    {
        var data = (List<Tuple<string, string>>)
                   info.GetValue("data", typeof(List<Tuple<string, string>>));
        foreach (var item in data)
            Add(int.Parse(item.Item1), int.Parse(item.Item2));
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        var data = new List<Tuple<string, string>>();
        foreach (var item in this)
            data.Add(Tuple.Create(item.Key.ToString(), item.Value.ToString()));
        info.AddValue("data", data, typeof(List<Tuple<string, string>>));
    }
}
...