2009-11-04 24 views
14

Al implementar la interfaz ISerializable en C#, proporcionamos un constructor que toma un objeto SerializationInfo y luego lo consulta con varios métodos GetInt32, GetObject etc. para rellenar los campos del objeto que intentamos deserializar.¿Por qué SerializationInfo no tiene métodos TryGetValue?

Una de las principales razones para implementar esta interfaz, en lugar de utilizar el atributo [Serializable], es para la compatibilidad hacia atrás: si hemos añadido nuevos campos a la clase en algún momento, podemos coger el SerializationException tirado por una versión serializada, mayores de la clase, y manejarlos de manera apropiada.

Mi pregunta es la siguiente: ¿por qué tenemos que usar estas excepciones para lo que es, esencialmente, flujo de control? Si estoy deserializando un gran número de clases que se guardaron hace algún tiempo, posiblemente cada campo faltante en cada clase arrojará una excepción, causando un rendimiento realmente malo.

¿Por qué la clase SerializationInfo no proporciona los métodos que simplemente devolverían false si la cadena del nombre no estuviera presente?

+0

Haz quienquiera implementado esa clase –

+4

bueno, tal vez están aquí: P –

Respuesta

23

Puede iterar sobre los campos disponibles y utilizar switch, aunque ...

  foreach(SerializationEntry entry in info) { 
       switch(entry.Name) { 
        ... 
       } 
      } 

O usted podría utilizar protobuf-net ;-P

+2

cool; esto no parece estar documentado en la documentación VS2008. –

+1

De acuerdo. Esto no parece estar documentado en ninguna parte. Nada parece decir que SerializationInfo es enumerable. Pero funcionó para mí. –

+1

@Michael excepto [aquí] (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator.aspx) por supuesto, o (@Joel) volviendo a 1.1, [ aquí] (http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator (v = VS.71) .aspx) –

0

Bueno nadie respondió 'por qué', pero 'm adivinando eso es dirigirse a la Sra ..

Mi aplicación para cualquier persona en necesidad:

public static class SerializationInfoExtensions 
{ 
    public static bool TryGetValue<T>(this SerializationInfo serializationInfo, string name, out T value) 
    { 
     try 
     { 
      value = (T) serializationInfo.GetValue(name, typeof(T)); 
      return true; 
     } 
     catch (SerializationException) 
     { 
      value = default(T); 
      return false; 
     } 
    } 

    public static T GetValueOrDefault<T>(this SerializationInfo serializationInfo, string name, Lazy<T> defaultValue) 
    { 
     try 
     { 
      return (T) serializationInfo.GetValue(name, typeof(T)); 
     } 
     catch (SerializationException) 
     { 
      return defaultValue.Value; 
     } 
    } 
} 
Cuestiones relacionadas