2010-08-09 13 views
6

Estoy serializando un diccionario a XML. Cuando se crea un nuevo diccionario que uso el constructor para proporcionar EqualityComparer sin carcasa, por ejemploDiccionario de serialización <cadena, objeto> cuando se inicializó el diccionario con el comparador de cadena insensible a mayúsculas o minúsculas

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

entonces serializar a XML y cuando Deserialize información acerca de carcasa está perdido - la deserialización se hace al diccionario con GenericEqualityComparer, que aparentemente es sensible a las mayúsculas y minúsculas, porque no encuentra mis llaves si no están correctamente colocadas.

¿Alguna idea de cómo puedo cambiarla?

Una forma sería crear un nuevo diccionario y copiar los datos del deserializado al nuevo, pero esto parece problemático.

ACTUALIZACIÓN:

La deserialización trabajaron todo el tiempo, es sólo que deserializa el Diccionario serializado a uno que no use las teclas de mayúsculas y minúsculas.

+0

¿Se produce este problema cuando se utiliza DataContract? –

+0

sí, la clase que contiene una propiedad de tipo Diccionario está marcada como DataContract y esta propiedad está marcada como DataMbember, si eso es lo que quería saber – mare

+0

Sí, lo era, pero ahora que se dio cuenta de que funciona en .NET 4.0, no hay nada que pueda seguir. Felicitaciones por resolver su propio problema. –

Respuesta

4

Sé que esta pregunta es bastante antigua, pero recientemente me encontré buscando cómo hacerlo.

Usando .Net4 (como @mare said), puede crear algunos métodos de extensión realmente agradables para que esto sea muy sencillo. Consulte https://stackoverflow.com/a/5941122/435460 para una implementación sencilla y sencilla.

Después de muchas excavaciones, esto funcionó como un encanto para mí.

3

Editar:

por los comentarios, parece que este enfoque puede ser obsoleta en .NET 4.

Fin Editar

Diccionarios suceder a requerir un poco de ayuda para serializar y deserializar

Aquí es un buen ejemplo de un diccionario Serializable XML:

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

Usted puede hacer que sea sensible a mayúsculas cambiando la declaración de la clase y la adición de un constructor, y ajustar una línea.

** EDITAR: error de sintaxis corregido a continuación./EDIT **

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

    // ... 
} 

Cambie la línea this.Add(key, value); a this[key] = value;.

En cualquier caso, es posible que tenga que dar masajes a algunos de los detalles, pero esto debería hacerlo sentir bien en el camino.

+0

Al trabajar con .NET 4, parece que el diccionario genérico es serializable, ya que funciona para mí. No estoy seguro de si es aconsejable implementar una solución a partir de 2006, dado que la implementación del nuevo diccionario o la implementación del DataContractSerializer son compatibles con la serialización/deserialización del diccionario desde el primer momento. – mare

+0

@mare: ¡Oye, son buenas noticias! Considere actualizar la etiqueta a .NET 4 y colocaré una edición en mi publicación. – kbrimington

+0

No se compila ya que 'La declaración de parámetro de tipo debe ser un identificador, no un tipo' para' cadena' en 'SerializableDictionary '. – JoeBilly

1

Sólo hay que concluir que su nuevo diccionario en el constructor:

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

Una vieja pregunta que me di cuenta, pero era más que cavar a través de la fuente de Dictionary y se dio cuenta que debería, de hecho, serializar el comparador:

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

Luego, en la implementación de IDeserializationCallback.OnDeserialization recupera los Compare:

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

Las clases que implementan la interfaz IDeserializationCallback especifican un método que se debe ejecutar después de que la instancia se haya deserializado, pero antes de que se devuelva a su código.

Ref: Dictionary.cs GetObjectData y OnDeserialization métodos

Cuestiones relacionadas