Я столкнулся с небольшим камнем преткновения в своем стремлении реализовать клонирование объектов в своем игровом движке.Моя цель - создать систему клонирования, которую мне не нужно поддерживать на уровне классов, если только класс не нуждается в особой обработке.
Настройка моего игрового движка вращается вокруг базового класса Object2D, который содержит некоторыеданные изображения в виде Texture2D.Что ж, долгая история заключается в том, что он содержит DisplayObject, который содержит Sprite, который содержит Texture2D.Естественно, другие классы, например, «Игрок», «Враг», «Снаряд» и т. Д., Все являются производными от базового класса Object2D.
К сожалению, я обнаружил, что класс XNA Texture2D не сериализуем.Это имеет смысл, поскольку мы не хотели бы копировать данные текстуры в памяти все вольно-невольно.
Это создает для меня дилемму.Я использовал методы глубокого клонирования для клонирования объектов, но так как он не сериализуем, я больше не могу этого делать.Я попытался просто пометить Texture2D [NonSerializable], но это вызывает проблемы при попытке рисовать, так как текстура клона нулевая.Мне не удалось найти какой-либо скрытый трюк, который бы позволил мне назначить его после клонирования (например, какой-то метод "onClone ()").
Так что я решил, что сделаю это.Для объектов, которые не могут быть глубоко клонированы в общем, я реализую интерфейс «SpecialClone», который позволяет мне указать метод clone ().
Однако, потому что класс, который не может быть глубоко клонированВ общем, это базовый класс, я вернулся к тому, с чего начал: написание метода клонирования для каждого класса по отдельности.
public static T clone<T>(T obj) {
if (obj == null) return default(T);
if (!typeof(T).IsSerializable) {
if (obj is SpecialClone) {
object obj2 = ((SpecialClone)obj).clone();
return (T)obj2;
} else {
throw new ArgumentException("Object type is not serializable.", "obj type: " + Type.GetTypeHandle(obj));
}
} else {
return deepClone(obj);
}
}
public static T deepClone<T>(T obj) {
if (obj == null) return default(T);
if (typeof(T).IsSerializable) {
try {
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
ms.Seek(0, SeekOrigin.Begin);
T obj2 = (T)bf.Deserialize(ms);
ms.Dispose();
return obj2;
}
catch (Exception e) {
Console.WriteLine(e);
return default(T);
}
} else {
Console.WriteLine(typeof(T) + " is not marked as serializable!");
return default(T);
}
}
С C # я пока не лучший, поэтому яЯ не уверен, что мне не хватает какой-то хитрости, которую я могу использовать, или это действительно то, как мне придется решать эту проблему.Основная цель этого клонирования - для типов Object2D, поэтому было бы очень трудно писать методы клонирования для каждого нового подкласса, который я создаю.
Есть ли способ избежать этого?