#c# #.net #class-design #binaryformatter
#c# #.net #класс-дизайн #binaryformatter
Вопрос:
В моем графе объектов у меня есть что-то вроде
[Serializable]
public class Dog
{
string _name;
}
и у меня есть всевозможные списки Dogs и ссылки на Dogs.
Поскольку Dog был только animal в начале создания программного обеспечения, у меня не было необходимости в каком-либо базовом классе. Теперь эта потребность возникла, и теперь я хотел бы иметь
[Serializable]
public class Dog : Animal
{
public void Bark() { }
}
[Serializable]
public class Cat : Animal
{
public void DoTheCatStuff() { }
}
[Serializable]
public class Animal
{
string _name;
}
НО: когда я десериализую СТАРЫЙ архив, у меня нет никаких dogs. Они вообще не десериализовались из архива.
Чего я хотел бы, так это несколько советов о том, как это сделать. Если мне понадобится новая иерархия классов и я вручную скопирую объекты из старого Dog в новый theDog, прекрасно, но хотелось бы избежать этого, если возможно.
РЕДАКТИРОВАТЬ: Некоторые .СЕТЕВЫЕ гуру, ПОЧЕМУ у меня нет никаких Dogs?
Комментарии:
1. Я выполнил простой тест с BinaryFormatter (сериализация, изменение определения класса, десериализация) с приведенным выше кодом, и я не увидел никакой проблемы. Вы уверены, что проблема в приведенном выше коде?
2. Попробуйте добавить список<Dog> в график объектов…
3. @Daniel, я повторил со списком<Dog>, но все еще не смог воспроизвести.
4. У вас правильно заполнен весь список производных Dogs? Несмотря на то, что вы переместили его закрытую часть в Animal?
5. Хорошо, я получаю список<Dog>, но поле, которое было перемещено (_name), не заполнено (т. Е. null).
Ответ №1:
Похоже, вам нужна реализация ISerializationSurrogate и некоторая магия SerializationBinder. Об этом есть очень хорошее обсуждение в старой колонке журнала MSDN.
Ответ №2:
Это интересный вариант; мой внутренний инстинкт заключается в том, чтобы сделать это:
Я бы написал программу обновления, которая имеет старый формат класса, который записывает его в новый формат, или промежуточный формат, который вы можете затем понять и преобразовать в свою новую иерархию классов.
Возможно, путем десериализации двоичного формата старого архива сериализуйте его в формате XML, а затем, возможно, используйте LinqToXml для создания объектов в вашей новой иерархии.
Комментарии:
1. В настоящее время я выполняю обновления таким образом, чтобы поддерживать int _serial в корне графика и выполнять что-то, когда serial не является самым новым. До сих пор (18 месяцев, 10 сайтов, около 20 обновлений) не было необходимости во внешней процедуре обновления…
2. Итак, является ли подклассирование ‘dog’ очень недавней вещью, которая вызвала эту проблему? Мне интересно, могли бы помочь некоторые атрибуты сериализации, допускающие версию, путем добавления обратного вызова для обработки значения: msdn.microsoft.com/en-us/library/ms229752 (v = против80).aspx
3. Я использую .net2.0, и в этом документе говорится, что он не обрабатывает атрибут VersionAdded. В любом случае, я не следовал рекомендациям из статьи и до сих пор не испытывал никаких проблем с (де) сериализацией.
4. Вы также должны знать, что двоичная сериализация по умолчанию ищет точные совпадения версий для определенных сборок. Например, я считаю, что для сборок со строгими именами версия сборки также должна совпадать. Я столкнулся с этой проблемой при попытке сохранить двоичные сериализованные объекты и повторно увлажнить их. Фактически, двоичная сериализация была такой проблемой при хранении на диске из-за проблем с управлением версиями, что в конечном итоге я выбрал архивированную, сериализованную версию XML.
5. Обрабатывала ли версия XML несколько ссылок на один и тот же объект? BinaryFormatter делает это.