StringBuilder wird beim Deserialisieren erst nach Verlassen des Deserialisierungskonstruktors gefüllt
-
Der folgende Quellcode:
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Text; namespace ConsoleApplication3 { [Serializable] class Test : ISerializable { [Serializable] private class InnerData { public StringBuilder Builder = new StringBuilder(); public string Str; } InnerData Data = new InnerData(); public Test() { } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { Data.Builder.Append("Test 1"); Data.Str = "Test 2"; info.AddValue("Data", Data); } private Test(SerializationInfo info, StreamingContext context) { Data = (InnerData)info.GetValue("Data", typeof(InnerData)); Output("ctor(SerializationInfo, context), nach info.GetValue"); } public void Output(string where) { Console.WriteLine(where + ":"); Console.WriteLine("Builder: " + (Data.Builder == null ? "Ist null" : Data.Builder.ToString())); Console.WriteLine("String: " + (Data.Str ?? "Ist null")); Console.WriteLine(); } } class Program { static void Main(string[] args) { Test test = new Test(); using (Stream stream = File.Open("Test.txt", FileMode.Create)) { new BinaryFormatter().Serialize(stream, test); } using (Stream stream = File.Open("Test.txt", FileMode.Open)) { Test test2 = (Test)new BinaryFormatter().Deserialize(stream); test.Output("Main, nach Deserialize"); } Console.ReadLine(); } } }
produziert folgende Ausgabe:
ctor(SerializationInfo, context), nach info.GetValue: Builder: Ist null String: Test 2 Main, nach Deserialize: Builder: Test 1 String: Test 2
Warum wird der StringBuilder erst auf einen gültigen Wert gesetzt, wenn der Konstruktor verlassen wurde und ist im Kontruktor noch null, obwohl GetValue schon aufgerufen wurde? Der String ist doch auch sofort korrekt.
-
Ne, is auch in main noch null.
Guck mal beitest.Output("Main, nach Deserialize")
...
test != test2
-
Ups. Kleiner Umbenennungsfehler. Das Phänomen bleibt aber trotzdem bestehen. (Ist der StringBuilder bei dir wirklich null oder war das nur die Vermutung aufgrund der falschen Variable? Denn null wäre ja erst recht falsch, da man erwartet, dass der StringBuilder deserialisiert wird.)
Korrigierter Code:
using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.Text; namespace ConsoleApplication3 { [Serializable] class Test : ISerializable { [Serializable] private class InnerData { public StringBuilder Builder = new StringBuilder(); public string Str; } InnerData Data = new InnerData(); public Test() { } void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { Data.Builder.Append("Test 1"); Data.Str = "Test 2"; info.AddValue("Data", Data); } private Test(SerializationInfo info, StreamingContext context) { Data = (InnerData)info.GetValue("Data", typeof(InnerData)); Output("ctor(SerializationInfo, context), nach info.GetValue"); } public void Output(string where) { Console.WriteLine(where + ":"); Console.WriteLine("Builder: " + (Data.Builder == null ? "Ist null" : Data.Builder.ToString())); Console.WriteLine("String: " + (Data.Str ?? "Ist null")); Console.WriteLine(); } } class Program { static void Main(string[] args) { Test test = new Test(); using (Stream stream = File.Open("Test.txt", FileMode.Create)) { new BinaryFormatter().Serialize(stream, test); } using (Stream stream = File.Open("Test.txt", FileMode.Open)) { Test test2 = (Test)new BinaryFormatter().Deserialize(stream); test2.Output("Main, nach Deserialize"); } Console.ReadLine(); } } }