Frage

Ich habe gerade etwas Verrücktes gemerkt, von dem ich angenommen hatte DataContractSerializer ruft den Konstruktor nicht auf !

Nehmen Sie zum Beispiel diese Klasse:

[DataContract]
public class Book
{
    public Book()
    { // breakpoint here
    }

    [DataMember(Order = 0)]
    public string Title { get; set; }
    [DataMember(Order = 1)]
    public string Author { get; set; }
    [DataMember(Order = 2)]
    public string Summary { get; set; }
}

Wenn ich ein Objekt dieser Klasse deserialisiere, wird der Haltepunkt nicht getroffen. Ich habe absolut keine Ahnung, wie es möglich ist, da es der einzige Konstruktor für dieses Objekt ist!

Ich nahm an, dass der Compiler möglicherweise wegen der Compiler ein zusätzlicher Konstruktor erzeugt wurde DataContract Attribut, aber ich konnte es nicht durch Reflexion finden ...

Also, was ich gerne wissen möchte, ist Folgendes: Wie könnte eine Instanz meiner Klasse erstellt werden, ohne dass der Konstruktor angerufen wird?

Hinweis: Ich weiß, dass ich das verwenden kann OnDeserializing Attribut zur Initialisierung meines Objekts Wenn die Deserialisierung beginnt, ist dies nicht Gegenstand meiner Frage.

War es hilfreich?

Lösung

DataContractSerializer (wie BinaryFormatter) verwendet nicht irgendein Konstrukteur. Es schafft das Objekt als leerer Speicher.

Zum Beispiel:

    Type type = typeof(Customer);
    object obj = System.Runtime.Serialization.
        FormatterServices.GetUninitializedObject(type);

Die Annahme ist, dass der Deserialisierungsprozess (oder bei Bedarf) ihn vollständig initialisiert.

Andere Tipps

Es gibt einige Szenarien, die ohne dieses Verhalten nicht möglich wären. Denken Sie an Folgendes:

1) Sie haben ein Objekt, das einen Konstruktor hat, der die neue Instanz in einen "initialisierten" Zustand festlegt. Dann werden einige Methoden auf diese Instanz aufgerufen, die sie in einen "verarbeiteten" Zustand bringen. Sie möchten keine neuen Objekte mit dem "verarbeiteten" Status erstellen, aber Sie möchten immer noch de serialisieren / deserialisieren die Instanz.

2) Sie haben eine Klasse mit einem privaten Konstruktor und einigen statischen Eigenschaften erstellt, um einen kleinen Satz zulässiger Konstruktorparameter zu steuern. Jetzt können Sie sie immer noch serialisieren / deserialisieren.

XMLSerializer hat das Verhalten, das Sie erwartet haben. Ich hatte einige Probleme mit dem XMLSerializer, da er einen Standardkonstruktor benötigt. Im Zusammenhang damit ist es manchmal sinnvoll, Privateigentumsetter zu haben. Der XMLSerializer benötigt aber auch öffentliche Getter und Setter für Eigenschaften, um zu serialisieren / zu deserialisieren.

Ich denke an das Verhalten von DataContractSerializer / Binaryformatter wie die Aufnahme des Zustands einer Instanz während der Serialisierung und der Wiederaufnahme während der Deserialisierung. Mit anderen Worten, die Instanzen sind nicht „konstruiert“, sondern in einem früheren Zustand „wiederhergestellt“.

Wie Sie bereits erwähnt haben, ermöglicht das Attribut für [OnDeserialisierende], nicht serialisierte Daten synchron zu halten.

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