2010-08-09 1 views
6

Я сериализую словарь в XML. Когда я создаю новый словарь я использовать конструктор, чтобы обеспечить EqualityComparer без кожуха, напримерСериализационный словарь <string, object>, когда словарь был инициализирован с помощью нечувствительного к регистру строкового сравнения

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

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

Любые идеи, как я могу его изменить?

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

UPDATE:

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

+0

Возникает ли эта проблема при использовании DataContract? –

+0

да, класс, который содержит свойство типа Dictionary , помечен как DataContract, и это свойство помечено как DataMbember, если это то, что вы хотели знать – mare

+0

Да, это было, но теперь, когда вы выяснили, что это работает в .NET 4.0, мне нечего отслеживать. Поздравляю с решением вашей собственной проблемы. –

ответ

4

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

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

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

3

Edit:

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

End Edit

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

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

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

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

** EDIT: Исправлена ​​ошибка синтаксиса ниже./EDIT **

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

    // ... 
} 

Изменение линии this.Add(key, value); к this[key] = value;.

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

+0

Работа с .NET 4 кажется, что общий словарь является сериализуемым, поскольку он работает для меня. Я не уверен, что реализация решения с 2006 года рекомендуется, учитывая, что новая реализация Dictionary или реализация DataContractSerializer поддерживают сериализацию/десериализацию словаря из коробки. – mare

+0

@mare: Эй, это хорошие новости! Пожалуйста, подумайте о том, чтобы обновить тег до .NET 4, и я поместил редактирование на свой пост. – kbrimington

+0

Не компилируется, так как 'Объявление параметра типа должно быть идентификатором, а не типом' для 'string' в' SerializableDictionary '. – JoeBilly

1

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

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

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

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

Тогда в реализации IDeserializationCallback.OnDeserialization он извлекает сравнить:

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

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

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

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