Сериализующий словарькогда словарь был инициализирован без учета регистра строк - PullRequest
6 голосов
/ 09 августа 2010

Я сериализую словарь в XML. Когда я создаю новый словарь, я использую конструктор, чтобы обеспечить EqualityComparer без регистра, например

var tabs = new Dictionary<string,Tab>(StringComparer.OrdinalIgnoreCase);

Затем я сериализуюсь в XML, и когда я десериализирую информацию о регистре, теряется - десериализация выполняется в Словаре с GenericEqualityComparer, который, очевидно, чувствителен к регистру, потому что он не находит мои ключи, если они не были правильно обработаны. 1004 *

Есть идеи, как мне это изменить?

Один из способов - создать новый словарь и скопировать данные из десериализованного в новый, но это кажется проблематичным.

UPDATE:

Десериализация работала все время, пока она просто десериализовала сериализованный словарь в тот, который не использует ключи без учета регистра.

Ответы [ 4 ]

4 голосов
/ 24 апреля 2012

Я знаю, что этот вопрос довольно старый, но недавно я начал искать, как это сделать.

Используя .Net4 (как сказал @mare), вы можете создать несколько действительно хороших методов расширения, чтобы сделать этолегкий ветерок.Изучите https://stackoverflow.com/a/5941122/435460 для хорошей и простой реализации.

После долгих копаний это сработало для меня как шарм.

3 голосов
/ 09 августа 2010

Редактировать:

Согласно комментариям, этот подход может быть устаревшим в .NET 4.

Конец редактирования

Словари нуждаются в небольшой помощи для сериализации и десериализации.

Вот хороший пример XML Serializable словаря:

http://weblogs.asp.net/pwelter34/archive/2006/05/03/444961.aspx

Вы можете сделатьон нечувствителен к регистру, изменяя объявление класса и добавляя конструктор и настраивая строку.

** РЕДАКТИРОВАТЬ: Исправлена ​​ошибка синтаксиса ниже./ РЕДАКТИРОВАТЬ **

public class SerializableDictionary<TValue>
    : Dictionary<string, TValue>, IXmlSerializable
{
    public SerializableDictionary()
        : base(StringComparer.InvariantCultureIgnoreCase)
    {
    }

    // ...
}

Измените строку this.Add(key, value); на this[key] = value;.

В любом случае, вам может понадобиться помассировать некоторые детали, но это должно помочь вамна дороге.

1 голос
/ 18 июля 2014

Старый вопрос, который я понимаю, но просто копался в источнике до Dictionary и заметил, что на самом деле он должен сериализовать Comparer:

info.AddValue(ComparerName, comparer, typeof(IEqualityComparer<tkey>));

Затем при реализации IDeserializationCallback.OnDeserialization он получаетComparar:

comparer = (IEqualityComparer<tkey>)m_siInfo.GetValue(ComparerName, typeof(IEqualityComparer<tkey>));

Классы, реализующие интерфейс IDeserializationCallback, определяют метод, который должен выполняться после десериализации экземпляра, но до его возврата в код.

Ref: Dictionary.cs Методы GetObjectData и OnDeserialization

1 голос
/ 04 октября 2012

Вам просто нужно свернуть свой новый словарь в конструкторе:

Dictionary<string, Tab> tabs ;
tabs = new Dictionary<string, Tab>((Dictionary<string, Tab>)serializer.ReadObject(reader),StringComparer.OrdinalIgnoreCase);
...