2009-01-19 11 views
16

Encontré un comportamiento extraño, al menos según mis expectativas, en la serialización binaria de .NET.Comportamiento extraño de .NET serialización binaria en el diccionario <Key, Value>

Todos los elementos de un Dictionary que se cargan se agregan a sus padres DESPUÉS de la devolución de llamada OnDeserialization. En contraste, List hace lo contrario. Esto puede ser realmente molesto en el código del repositorio del mundo real, por ejemplo, cuando necesita agregar delegados a los elementos del diccionario. Por favor, compruebe el código de ejemplo y mire las afirmaciones.

¿Es normal el comportamiento?

[Serializable] 
public class Data : IDeserializationCallback 
{ 
    public List<string> List { get; set; } 

    public Dictionary<string, string> Dictionary { get; set; } 

    public Data() 
    { 
     Dictionary = new Dictionary<string, string> { { "hello", "hello" }, { "CU", "CU" } }; 
     List = new List<string> { "hello", "CU" }; 
    } 

    public static Data Load(string filename) 
    { 
     using (Stream stream = File.OpenRead(filename)) 
     { 
      Data result = (Data)new BinaryFormatter().Deserialize(stream); 
      TestsLengthsOfDataStructures(result); 

      return result; 
     } 
    } 

    public void Save(string fileName) 
    { 
     using (Stream stream = File.Create(fileName)) 
     { 
      new BinaryFormatter().Serialize(stream, this); 
     } 
    } 

    public void OnDeserialization(object sender) 
    { 
     TestsLengthsOfDataStructures(this); 
    } 

    private static void TestsLengthsOfDataStructures(Data data) 
    { 
     Debug.Assert(data.List.Count == 2, "List"); 
     Debug.Assert(data.Dictionary.Count == 2, "Dictionary"); 
    } 
} 
+0

Me resulta difícil seguir las respuestas porque ¡tu instancia de objeto tiene el mismo nombre que la clase! ¿Cómo se puede distinguir entre métodos estáticos y miembros? –

Respuesta

8

Puedo reproducir el problema. Eché un vistazo a Google y encontré esto: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94265 aunque no estoy seguro de que sea exactamente el mismo problema, parece bastante similar.

EDIT:

Creo que la adición de este código puede haber solucionado el problema?

public void OnDeserialization(object sender) 
    { 
      this.Dictionary.OnDeserialization(sender); 
    } 

No hay tiempo para probar de manera exhaustiva, y quiero vencer a Marc a la respuesta ;-)

+0

Creo que lo encontramos aproximadamente al mismo tiempo; tal vez me has superado, así que +1 a ti ;-p –

+0

De hecho, mi publicación señaló eso mucho antes de tu edición: ( –

+0

Y +1 a los dos :-) – endian

4

interesante ... para obtener información, lo probé con el enfoque basado en atributos (más abajo), y se comporta de la misma ... muy curioso! No puedo explicarlo - Sólo estoy respondiendo a confirmar reproducida, y mencionar el comportamiento [OnDeserialized]:

[OnDeserialized] // note still not added yet... 
private void OnDeserialized(StreamingContext context) {...} 

Editar - encontrado "conectar" cuestión here. Intente agregar a su devolución de llamada:

Dictionary.OnDeserialization(this); 
+3

Solo para hacerte saber que el enlace ha muerto – Jeb

10

Sí, usted ha descubierto una peculiaridad molesta en Dictionary<TKey, TValue> deserialización. Se puede conseguir alrededor de él llamando manualmente OnDeserialization() método del diccionario:

public void OnDeserialization(object sender) 
{ 
    Dictionary.OnDeserialization(this); 
    TestsLengthsOfDataStructures(this); 
} 

Por cierto, también puede utilizar el atributo [OnDeserialized] en lugar de IDeserializationCallback:

[OnDeserialized] 
public void OnDeserialization(StreamingContext context) 
{ 
    Dictionary.OnDeserialization(this); 
    TestsLengthsOfDataStructures(this); 
} 
+0

Ninguna leve intención, Kent; +1 –

+0

Solo para agregar una palabra de advertencia: en mi entorno, intentar agregar a un diccionario deserializado antes de llamar a su 'OnDeserialization' me llevaba a' NullReferenceException' generado desde dentro del diccionario. – Nathan

Cuestiones relacionadas