Warum kann das ‚NonSerialized‘ Attribut auf Klassenebene verwendet werden? Wie Serialisierung einer Klasse zu verhindern?

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

Frage

ich ein Datenobjekt, die tief geklont wird eine binäre Serialisierung verwenden. Dieses Datenobjekt unterstützt Eigenschaft geändert Ereignisse, zum Beispiel PriceChanged.

Lassen Sie uns sagen angebracht ich einen Handler PriceChanged. Wenn der Code versucht PriceChanged zu serialisiert, es löst eine Ausnahme, dass der Handler nicht als serialisierbar gekennzeichnet ist.

Meine Alternativen:

  • Ich kann nicht ohne weiteres entfernen Sie alle Handler aus dem Ereignis vor der Serialisierung
  • Ich will nicht den Handler als serialisierbar markieren, weil ich rekursiv auch alle Handler Abhängigkeiten würde markieren.
  • Ich will nicht als NonSerialized PriceChanged markieren - es gibt Dutzende von Veranstaltungen wie diese, die möglicherweise Handler haben könnte. EDIT: Ein weiterer Grund, warum ich nicht tun kann, ist dies, weil die Datenklassen (und damit die Ereignisse) erzeugt werden, und ich habe keine direkte Kontrolle über die Erzeugung Code. Idealerweise würde die Generation Code nur alle Ereignisse als NonSerialized markiert.
  • Idealerweise möchte ich .NET nur Stopp an diesem Punkt das Objekt Diagramm geht zurück und macht, dass ein ‚Blatt‘. Warum .NET nicht eine ganze Klasse erlauben als NonSerialized markiert werden?

-

ich endlich, um dieses Problem gearbeitet, indem der Handler ISerializable implementieren und im serialize Konstruktor / getDataObject Verfahren nichts zu tun. Aber nach wie vor dem Handler wird serialisiert, nur mit allen seinen Abhängigkeiten auf null - so dass ich für das auch auf Rechnung hatte.

Gibt es eine bessere Art und Weise Serialisierung einer ganzen Klasse zu verhindern? Das heißt, eine, die für die Null-Abhängigkeiten nicht Buchhaltung erforderlich?

War es hilfreich?

Lösung

Während ich mit dem Ansatz eher ablehnen (ich einfach die Ereignisse als NonSerialized markieren würde, unabhängig davon, wie viele es sind) Sie wahrscheinlich diese Surrogate mit Serialisierung tun könnte.

Die Idee ist, dass Sie ein Objekt erstellen, dass Geräte ISerializationSurrogate und im Grunde tut, was Sie bereits tun - nichts in dem GetObjectData und SetObjectData Methoden. Der Unterschied besteht darin, dass Sie die Serialisierung der Delegierten würden Customizing, nicht die Klasse enthält es.

So etwas wie:

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

Dann registrieren Sie dies mit dem Formatierer, die Verfahren unter Verwendung von in diesem MSDN Spalte skizziert . Dann, wenn der Formatierer einen Delegierten trifft, verwendet es den Ersatz statt serializating den Delegaten direkt.

Andere Tipps

  

... gibt es Zehn Veranstaltungen ...

Persönlich dann würde ich nur hinzufügen, die nicht serialisiert Marker, die für feldartigen Ereignisse wird am einfachsten über:

[field: NonSerialized]
public event SomeEventType SomeEventName;

(Sie brauchen nicht eine manuelle Unterstützung Delegaten hinzuzufügen)

Was sind Ihre Serialisierungsanforderungen genau? BinaryFormatter ist in vielerlei Hinsicht die am wenigsten freundlich der Serializer; die Auswirkungen auf die Ereignisse sind ein bisschen hässlich, und es ist sehr spröde, wenn gespeichert (IMO es nur wirklich geeignet für den Transport ist, nicht für die Lagerung).

Allerdings; es gibt viele gute Alternativen, die am häufigsten „deep clone“ Szenarien unterstützen würde:

  • XmlSerializer (aber beschränkt auf öffentliche Mitglieder)
  • DataContractSerializer / NetDataContractSerializer
  • protobuf-net (die Serializer.DeepClone zu diesem Zweck enthält)

(beachten Sie, dass in den meisten dieser Serialisierung Unterstützung würde zusätzliche Attribute erfordern, so dass nicht viel anders als das Hinzufügen der [NonSerialized] in erster Linie Attribute!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top