¿Por qué no puede el atributo 'NonSerialized' se utiliza a nivel de clase? ¿Cómo prevenir la serialización de una clase?

StackOverflow https://stackoverflow.com/questions/2467376

Pregunta

Tengo un objeto de datos que está profundamente clonado utilizando una serialización binaria. Este objeto de datos soporta propiedad eventos modificados, por ejemplo, PriceChanged.

Digamos que me adjunta un controlador de PriceChanged. Cuando el código intenta serializar PriceChanged, se produce una excepción de que el controlador no está marcado como serializable.

Mis alternativas:

  • No puedo quitar fácilmente todos los manejadores del evento antes de la serialización
  • No quiero a marcar el controlador como serializable, ya que tendría que marcar de forma recursiva todas las dependencias manipuladores también.
  • No quiero para marcar PriceChanged como NonSerialized - hay decenas de eventos como este que podría tener potencialmente manipuladores. EDIT: Otra razón por la que no pueden hacer esto se debe a que las clases de datos (y por tanto los eventos) se generan y que no tienen control directo sobre la generación de código. Idealmente, el código de generación solo marcaría todos los eventos como NonSerialized.
  • Idealmente, me gustaría .NET para simplemente dejar de ir por el gráfico de objetos en ese punto y hacer que una 'hoja'. ¿Entonces por qué no permite que toda una clase .NET para ser marcado como NonSerialized?

-

Finalmente evitaron el problema haciendo que el manejador de implementar ISerializable y no hacer nada en el método / GetDataObject serializar constructor. Sin embargo, el controlador sigue siendo serializado, acaba con todas sus dependencias como nulas - así que tuve que dar cuenta de eso también.

¿Hay una mejor manera de prevenir la serialización de una clase entera? Es decir, uno que no requiere dar cuenta de las dependencias nulos?

¿Fue útil?

Solución

Si bien tiendo a estar en desacuerdo con el enfoque (I simplemente marcaría el NonSerialized eventos como, independientemente de cuántos hay) que probablemente se podría hacer esto utilizando sustitutos de serialización.

La idea es que se crea un objeto que implementa ISerializationSurrogate y básicamente hace lo que ya está haciendo - nada en el GetObjectData y métodos SetObjectData. La diferencia es que usted sería la personalización de la serialización del delegado, no a la clase que lo contiene.

Algo así como:

class DelegateSerializationSurrogate : ISerializationSurrogate {
    public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        // do nothing
    }
    public object SetObjectData(object obj, SerializationInfo info, StreamingContext context) {
        // do nothing
        return null;
    }
}

A continuación, se registra esto con el formateador usando los procedimientos se indica en esta columna de MSDN . Entonces cada vez que el formateador encuentra un delegado, se utiliza el sustituto en lugar de serializating el delegado directamente.

Otros consejos

  

... hay decenas de eventos ...

En lo personal, entonces me acaba de añadir a los marcadores no serializados, que para los eventos de campo al igual que se hace más fácilmente a través de:

[field: NonSerialized]
public event SomeEventType SomeEventName;

(que no es necesario agregar un delegado respaldo manual)

¿Cuáles son sus requisitos de serialización exactamente? BinaryFormatter es en muchos aspectos el menos agradable de los serializadores; las implicaciones de eventos son un poco feo, y es muy frágil si se almacena (OMI sólo es realmente adecuado para el transporte, no para el almacenamiento).

Sin embargo; hay un montón de buenas alternativas que apoyaría escenarios más comunes "clonar" profunda:

  • XmlSerializer (pero limitado a los miembros públicos)
  • DataContractSerializer / NetDataContractSerializer
  • protobuf-net (que incluye Serializer.DeepClone para este propósito)

(nótese que en la mayoría de los serialización de apoyo requeriría atributos adicionales, por lo que no es muy diferente a la adición de los atributos de [NonSerialized] en el primer lugar!)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top