Ich konvertiere ein Java-Spiel in C# (Titan Attacks von Puppy Games) und bin ziemlich viel jetzt abgesehen von der letzten Aufgabe, die Serialisierung des Spiels Zustand ist für Sicherungsdateien..Net Serialisierung - Mischen [Serializable] mit benutzerdefinierten in Vererbungsbaum
Typische Hierarchie: Ressource (Basis) -> Feature-> Screen/Wirkung/Entity-> GameScreen/LaserEffect/Invader
der Java-Code verwendet Standard Objectoutput/Object binäre Serialisierung durchzuführen, aber annoyingly führt einige readResolve/writeResolve arbeitet auf der Basisklassenebene (Resource), um den Serialisierungsprozess anzupassen (wenn eine Ressource benannt wird, wird sie nicht serialisiert und gibt einfach einen Proxy mit einem Namen zurück, der später zum Abrufen der Ressource aus einer Hashmap verwendet wird).
Meine naiven Lösungen sind blind, diesen Ansatz zu kopieren und ISerializable in der Basisklasse implementieren die TYPE ...
public virtual void GetObjectData(SerializationInfo info, StreamingContext context) {
if (name != null) {
// Got a name, so send a SerializedResource that just references us
info.AddValue("name", this.name);
info.SetType(typeof(SerializedResource));
return;
}
//Serialize just MY fields (defined in Resource)
this.SerializeMyFields(info, context, typeof(Resource));
}
Q außer Kraft zu setzen) Also, ich bin ziemlich sicher, dass alle Wetten ausgeschaltet sind für gebaut -in Serialisierung und ich muss ISerializable die Erbschaftskette zusammen mit dem Serialisierungskonstruktor vollständig implementieren?
Hinweis GetObjectData ist virtuell, daher können abgeleitete Klassen ihre Felder serialisieren und dann die Basisklasse aufrufen. Das funktioniert, aber es ist eine Menge langweiliger Arbeit, die zu vielen Klassen (100s) hinzukommt.
Einige abgeleitete Typen (Sprite, InvaderBehaviour, usw.) führen auch benutzerdefinierte Serialisierungsarbeiten durch, um die Sache noch schlimmer zu machen.
Ich habe Jeffrey Richters Artikel zu diesem Thema angeschaut und versucht, ein ResourceSurrogateSelector: ISerializationSurrogate-Typ-Konstrukt zu verwenden, aber diese Serialisierungsmethoden werden nur aufgerufen, wenn der serialisierte Typ eine Ressource und kein von Ressource abgeleiteter Typ ist nicht aufgerufen werden Serialisierung eines Invader oder GameScreen)
Q) gibt es eine kluge Möglichkeit, dies zu tun?
Ich habe es geschafft, die beiden Code-Basen ziemlich nahe beieinander zu halten und das hat die Konvertierung viel einfacher gemacht - ich würde diesen Ansatz hier fortsetzen (also kein XmlSerializer, Protobuf, etc), es sei denn wirklich zwingenden Grund nicht zu.
Ich habe darüber nachgedacht, Java zu schreiben, um den Prozess zu automatisieren und die Typen zu implementieren, die die Serializable-Schnittstelle implementieren und eine .cs-Datei mit dem gesamten .Net-Serialisierungscode erstellen, damit ich die Hauptklassendateien nicht verschmutze (Ich würde sie teilweise machen)
PS - Zielplattformen werden Windows8/Surface/XBox360 auf der .Net-Seite der Dinge sein (so Version 4) und wahrscheinlich PS Vita/vielleicht iOS mit Mono. Saves werden auf der Plattform, auf der sie serialisiert wurden, deserialisiert.
EDIT Eine Antwort von Sergey Teplyakov in diesem Beitrag .... .NET, C#: How to add a custom serialization attribute that acts as ISerializable interface ... hat mich zu dem ISurrogateSelector Schnittstelle geführt, wie es den gewünschten abgeleiteten Klassen mit der Auswahl helfen aussieht.