2008-12-05 18 views

Respuesta

34

Sí y no. Como Jeff y otros han señalado, todas las clases de excepción deben ser, y casi siempre, serializables. Si te encuentras con una clase de excepción particular que no es serializable, es muy posiblemente un error.

Pero al considerar la serializabilidad, debe considerar tanto la clase inmediata como todos los tipos que son miembros de este tipo (este es un proceso recursivo). La clase Excepción base tiene una propiedad Data que es del tipo IDictionary. Esto es problemático porque le permite a usted, o a cualquier otra persona, agregar cualquier objeto en la Excepción. Si este objeto no es serializable, la serialización de la excepción fallará.

La implementación predeterminada de la propiedad Data realiza una comprobación básica para garantizar que un objeto que se está agregando sea serializable. Pero es deficiente en varios aspectos

  • sólo la parte superior nivel de la comprobación de la secuencialidad de un tipo y esta comprobación se realiza sólo mediante la comprobación Type.IsSerializable (no un cheque sólida 100%).  
  • La propiedad es virtual. Un tipo de excepción derivada podría anular y usar una Hashtable que hace 0 comprobación.
15

Sí, pero históricamente ha habido (sin doble sentido) excepciones.

En otras palabras, todas las excepciones deben serializable, pero algunas excepciones personalizadas de código de terceros pueden no ser, dependiendo de lo que se implementen.

Por ejemplo, en la era de .NET 1.0, las excepciones del proveedor oficial de la base de datos Oracle de Oracle no se pudieron serializar, debido a errores en su código.

+1

Incluso a partir de .Net 4.5, algunas excepciones de la base de datos OleDB y algunas excepciones de System.Net no son deserializables, debido a la falta del constructor requerido. – ricovox

6

System.Exception implementa ISerializable, pero los descendientes pueden no deserializar si no implementan el constructor correcto sobrecargado con firma (SerializationInfo,StreamingContext).

+1

Además, si una excepción derivada no llama correctamente a base.GetObjectData, la información de la excepción base no se serializará, lo que daría lugar a errores en la deserialización. En cualquier caso (constructor faltante o falla al serializar la base), la serialización tendrá éxito, pero la deserialización generará una excepción. – ricovox

8

Esta cuestión ya se ha dado respuesta suficiente, pero para los programadores que son nuevos en C# o de serialización, creo que en realidad es muy útil señalar que, en general, las excepciones son NO serializable!

Eso puede sonar un poco provocativo, pero déjame explicarte.

Es cierto que todas las Excepciones implementan la interfaz ISerializable, pero esto solo sugiere que sea serializable. Pero implementar la interfaz NO hace que un objeto sea serializable (lo que en este contexto implica que la excepción puede ser serializada y deserializada).

La respuesta más precisa a esta pregunta, como han señalado otros, es que muchas pero no todas las excepciones en el .NET Framework son serializables.Pero si la pregunta es usar el término ".Net Exception" en un ámbito más amplio, p. una excepción derivada de System.Exception, entonces la respuesta mejor y más útil, en términos de mejores prácticas y evitar errores, es la afirmación que hice anteriormente, que en general las excepciones no son serializables.

He aquí por qué: Como se dijo anteriormente, para que una excepción sea verdaderamente serializable, debe tener el constructor apropiado ctor(SerializationInfo, StreamingContext) y debe estar decorado con el atributo adecuado. Es importante destacar que ninguna de estas restricciones causa errores en el compilador si se omiten.

Lo que esto significa es que NO NO clase derivada de Exception es Serializable a menos que se tomen estos pasos adicionales, opcionales (desde la perspectiva del compilador).

I.e. cualquier codificador inconsciente/no consciente que derive una nueva excepción como la siguiente acaba de crear una excepción que NO es serializable.

class MyNewException : Exception { } 

Visual Studio tiene un gran fragmento de "excepción" que le permite generar nuevas excepciones serializables con bastante rapidez. Pero incluso en este caso, no hay nada que recordar o ayudar al programador a serializar realmente las propiedades del objeto. Por ejemplo, incluso si la clase siguiente tuviera el constructor y el atributo apropiados, la propiedad MyNewField no se serializaría sin código adicional tanto en el constructor como en GetObjectData.

class MyNewException : Exception 
{ 
    public MyNewField { get; set; } 
} 

Por lo tanto, el punto importante aquí es que si hay que confiar en la serialización de excepción adecuada & deserialización por alguna razón, debe ser completamente consciente de que cuando se trata de cualquier código personalizado o asambleas, no hay ninguna garantía de que trabajará. Además, dado que el constructor requerido generalmente está protegido, no necesariamente podrá verificar fácilmente que esté presente (sin reflejo).

En mis propios proyectos, he creado en algunos puntos excepciones "Proxies" que pueden almacenar parte de la información (por ejemplo, mensajes, etc.) de Excepciones que no son serializables. Se pueden usar para serializar parte de la información, o alternativamente para deserializar datos escritos por una Excepción que no tiene el constructor apropiado.

Cuestiones relacionadas