ISerializable probleme mit parameterisiertem Konstruktor

gott_ad

Grünschnabel
Hi,

ich hab hier mal folgendes funktionierendes Minimalbeispiel gebaut:
Code:
using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace BinarySerialisierungsTest {
	// Einstiegsklasse
	class MainClass {
		[STAThread]
		public static void Main(string[] args) {
			FileStream fs = new FileStream(@"c:\serialisierungstest.dat",FileMode.Create);
			BinaryFormatter bf = new BinaryFormatter();
			Unterklasse u = new Unterklasse("u");
			bf.Serialize(fs, u);
			fs.Close();
		}
	}//end MainClass
	
	[Serializable]
	public class Oberklasse{
		public Oberklasse(string ausgabe){
			Console.WriteLine("ich bin OBERKLASSE und soll: "+ausgabe+" sagen");
		}
	}// end Oberklasse
	
	[Serializable]
	public class Unterklasse : Oberklasse {
		private int some_number = 5;
		private string parameter = "";
		[NonSerialized] System.Windows.Forms.Form eineForm = new System.Windows.Forms.Form();
		public Unterklasse(string ausgabe2) : base (ausgabe2){
			Console.WriteLine("ich bin UNTERKLASSE und soll: "+ausgabe2+" sagen");
			parameter = ausgabe2;
			eineForm.ShowDialog();
		}
	}// end Unterklasse
}// end namespace
Soweit läuft das Beispiel. Weil ich Windows.Forms.Form nicht serialisieren kann, hab ich sie als [NonSerialized] deklariert. Soweit alles wie ich es will.

Jetzt das eigentliche Problem. Ich finde es sehr umständlich über alle Attribute [NonSerialized] zu setzen. Deshalb gibt es ja die Möglichkeit das ISerializable Interface zu implementieren. Entsprechend würde die geänderte Unterklasse so aussehen:
Code:
	[Serializable]
	public class Unterklasse : Oberklasse, ISerializable {
		private int some_number = 5;
		private string parameter = "";
		System.Windows.Forms.Form eineForm = new System.Windows.Forms.Form();
		public Unterklasse(string ausgabe2) : base (ausgabe2){
			Console.WriteLine("ich bin UNTERKLASSE und soll: "+ausgabe2+" sagen");
			parameter = ausgabe2;
			eineForm.ShowDialog();
		}
		protected Unterklasse(SerializationInfo info, StreamingContext context){
			some_number = info.GetInt16("Number");
			parameter = info.GetString("Parameter");
		}
		void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context){
			info.AddValue("Number",some_number);
			info.AddValue("Parameter",parameter);
		}
	}// end Unterklasse
Das Problem hierbei ist, dass man zum Deserialisieren einen zweiten Konstruktor erstellen muss. Soweit wäre das nicht schlimm, aber mein Konstruktor MUSS den Konstruktor der Oberklasse aufrufen und muss diesem auch einen Parameter übergeben. Den zu übergebenen Parameter könnte ich auch serialisieren (mach ich ja im Beispiel mit dem Attribut "string parameter") und dann wieder deserialisieren und den originalkonstruktor per Hand aufrufen und per hand den Parameter übergeben, aber soweit komme ich leider nicht. Das Beispiel wird nicht kompiliert, weil der zweite Konstruktor (zum deserialisieren) nicht die Oberklasse aufruft. Habt ihr irgendwelche Ideen?
Gruß gott_ad
 
Okay, ich habs!
In Oberklasse muss ebenfalls ein zweiter Konstruktor eingefügt werden (Oberklasse braucht nicht das ISerializable Interface):
Code:
protected Oberklasse(SerializationInfo info, StreamingContext context){
}

und in der Unterklasse muss der zweite Konstruktor so abgeändert werden:
Code:
protected Unterklasse(SerializationInfo info, StreamingContext context):base(info,context){
	some_number = info.GetInt16("Number");
	parameter = info.GetString("Parameter");
}
(das :base(...) ist neu)
 
Zurück