Perché non è possibile l'attributo 'NonSerialized' essere utilizzato a livello di classe? Come prevenire la serializzazione di una classe?

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

Domanda

Ho un oggetto di dati che è profondamente clonato utilizzando una serializzazione binaria. Questo oggetto dati supporta proprietà eventi modificati, per esempio, PriceChanged.

Diciamo che ho attaccato un gestore di PriceChanged. Quando il codice tenta di serializzare PriceChanged, viene generata un'eccezione che il gestore non è contrassegnato come serializzabile.

I miei alternative:

  • Non riesco a rimuovere facilmente tutti i gestori dall'evento prima di serializzazione
  • Non voglio per contrassegnare il gestore come serializzabile, perché avrei dovuto segnare in modo ricorsivo tutti i gestori dipendenze pure.
  • Non desidera contrassegnare come PriceChanged NonSerialized - ci sono decine di eventi come questo che potrebbe potenzialmente avere i gestori. EDIT: Un altro motivo per cui non possono fare questo è perché le classi di dati (e quindi gli eventi) vengono generati e non ha il controllo diretto generazione del codice. Idealmente, la generazione del codice sarebbe solo contrassegnare tutti gli eventi come NonSerialized.
  • Idealmente, vorrei .NET di fermarsi solo andando verso il basso l'oggetto grafico in quel punto e fare che una 'foglia'. Allora perché non NET consente un'intera classe per essere contrassegnato come NonSerialized?

-

Alla fine ho lavorato intorno a questo problema rendendo il gestore implementare ISerializable e non fare nulla nel metodo / GetDataObject costruttore serialize. Ma, il gestore è ancora serializzato, solo con tutte le sue dipendenze impostato su null - quindi ho dovuto tenere conto di quello.

C'è un modo migliore per prevenire la serializzazione di un'intera classe? Cioè, uno che non richiede la contabilità per le dipendenze nulli?

È stato utile?

Soluzione

Mentre io tendo a non essere d'accordo con l'approccio (vorrei semplicemente segnare i gli eventi come NonSerialized, a prescindere da quanti ce ne sono) si potrebbe probabilmente fare questo usando surrogati di serializzazione.

L'idea è che si crea un oggetto che implementa ISerializationSurrogate e fondamentalmente fa quello che si sta già facendo - nulla nel GetObjectData e metodi SetObjectData. La differenza è che si sarebbe personalizzando la serializzazione del delegato, non la classe che lo contiene.

Qualcosa di simile:

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;
    }
}

Poi si registra questo con il formattatore utilizzando le procedure delineato in questa colonna MSDN . Poi quando il formattatore incontra un delegato, esso utilizza il surrogato anziché serializating direttamente delegato.

Altri suggerimenti

  

... ci sono decine di eventi ...

Personalmente, quindi mi piacerebbe solo aggiungere i marcatori non serializzati, che per gli eventi sul campo come è più facilmente effettuata tramite:

[field: NonSerialized]
public event SomeEventType SomeEventName;

(non è necessario aggiungere un supporto delegato manuale)

Quali sono esattamente le vostre esigenze di serializzazione? BinaryFormatter è per molti versi la meno amichevoli dei serializzatori; le implicazioni sugli eventi sono un po 'brutto, ed è molto fragile se conservato (IMO è solo veramente adatto per il trasporto, non per lo stoccaggio).

Tuttavia; ci sono un sacco di buone alternative che supportasse più comuni scenari di "profondo clone":

  • XmlSerializer (ma limitato ai soci pubblici)
  • DataContractSerializer / NetDataContractSerializer
  • protobuf-net (che include Serializer.DeepClone per questo scopo)

(si noti che nella maggior parte di coloro sostegno serializzazione richiederebbe attributi extra, in modo non molto diverso per l'aggiunta di attributi [NonSerialized] in primo luogo!)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top