Konwertuję grę Java na C# (Ataki tytanów przez Puppy Games) i jestem prawie zajęta teraz, oprócz ostatniego zadania, które jest serializacją stanu gry dla plików zapisu.Serializacja serialu - mieszanie [Serializable] z niestandardowym drzewem dziedziczenia
Typowe hierarchia: zasób (zasada) -> Feature-> Ekran/Działanie/Entity-> GameScreen/LaserEffect/Invader
kod Java wykorzystuje standardowe ObjectOutputStream/ObjectInputStream do wykonania serializacji binarnej, ale nieznośno wykonuje pewne readResolve/writeResolve działa na poziomie klasy podstawowej (Zasób), aby dostosować proces serializacji (jeśli zasób jest nazwany, nie przekształca go do postaci szeregowej i po prostu zwraca serwer proxy o nazwie używanej później do pobrania zasobu z mapy mieszającej).
moje naiwne rozwiązania jest ślepo kopiować to podejście i wdrożyć ISerializable w klasie bazowej przesłonić typu ...
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) Tak, jestem pewien, że wszystkie zakłady są wyłączone do zabudowy -w serializacji i muszę zaimplementować ISerializable do końca łańcucha dziedziczenia wraz z konstruktorem serializacji?
Uwaga Klasa GetObjectData jest wirtualna, więc klasy pochodne mogą serializować ich pola, a następnie wywoływać klasę podstawową. Działa to, ale jest to mnóstwo żmudnej pracy dodając do wielu klas (100).
Niektóre typy pochodne (Sprite, InvaderBehavour, itp.) Również wykonują niestandardową pracę serializacyjną, aby pogorszyć sprawę.
Przyjrzałem się artykułom Jeffreya Richtera na ten temat i próbowałem użyć konstruktu typu ResourceSurrogateSelector: ISerializationSurrogate, ale te metody serializacji są wywoływane tylko wtedy, gdy typ serializowany jest zasobem, a nie typem pochodzącym z zasobu (np. nie zostanie wywołana serializowanie Invadera lub GameScreen)
Q) Czy istnieje inteligentny sposób na zrobienie tego?
Udało mi się utrzymać dwie bazy kodowe bardzo blisko siebie, co znacznie ułatwiło konwersję - chciałbym kontynuować to podejście tutaj (więc nie ma XmlSerializer, Protobuf, itp.), Chyba że jest naprawdę przekonujący powód, by tego nie robić.
Zastanawiam się nad napisaniem Java, aby zautomatyzować proces i odzwierciedlić typy implementujące interfejs Serializable i utworzyć plik .cs ze wszystkimi kodami serializacji .Net, aby nie zanieczyszczać plików głównej klasy (Zrobiłbym je częściowe)
PS - Docelowymi platformami będą Windows8/Surface/XBox360 po stronie .Net (więc wersja 4) i prawdopodobnie PS Vita/może iOS używający Mono. Zapisane dane są deserializowane na platformie, na której zostały serializowane.
EDIT Odpowiedź przez Sergey Teplyakov w tym poście .... .NET, C#: How to add a custom serialization attribute that acts as ISerializable interface ... doprowadziły mnie do interfejsu ISurrogateSelector która wygląda jak to pomoże w wyborze odpowiednich klas pochodnych.