Как я могу прочитать данные из сериализованного объекта, определение которого больше не находится в моей кодовой базе? - PullRequest
2 голосов
/ 15 июня 2011

Скажите, у меня есть следующий класс:

[Serializable]
public class A
{
    public string B { get; set; }
}

и для его сериализации использовался следующий метод:

public void Serialize()
{
    BinaryFormatter b = new BinaryFormatter();
    b.Serialize(new FileStream(@"C:\Temp\out.dat", FileMode.Create), new A());
}

Если в какой-то момент кто-то пришел и изменил определение класса, чтобы оно содержало дополнительное свойство (или удалило одно):

[Serializable]
public class A // Same class
{
    public string B { get; set; }
    public string C { get; set; } // New property
}

тогда сломается следующее:

public void Deserialize()
{
    BinaryFormatter b = new BinaryFormatter();
    A deserialized = (A)b.Deserialize(new FileStream(@"C:\Temp\out.dat", FileMode.Open));
}

потому что сериализованная версия класса не соответствует определению класса нового класса.

Мне действительно не нравится идея сериализации как механизма персистентности, потому что она очень хрупкая. Я бы справился с этим гораздо раньше, если бы участвовал в принятии решения.

Есть ли какой-нибудь способ привести мои сериализованные данные в форму, которую я могу прочитать, не возвращая все мои текущие определения классов в их сериализованное состояние?

Даже если бы это было хакерским «по максимуму», я надеялся, что смогу сделать это, потому что я надеюсь, что сделаю это только один раз (или пока я не смогу выяснить, как исправить корень проблемы).

редактировать

В моей системе уже есть десятки этих классов, которые были сериализованы, а затем изменены. Невозможно использовать контроль версий, чтобы точно определить, когда и как изменился каждый отдельный класс.

В настоящее время я пытаюсь выяснить, каким образом я могу сохранить настройки «старой А» до того, как пользователь попытается десериализовать объект в формате «новой А», и мне нужно 1) попытаться, 2) поймать, 3) проглотить ошибку и, наконец, 4) воссоздать A со значениями по умолчанию (на основе нового определения объекта).

1 Ответ

2 голосов
/ 15 июня 2011

Я полагаю, что вы можете украсить новых добавленных членов с помощью OptionalFieldAttribute (пространство имен System.Runtime.Serialization), которое позволит вам десериализовать экземпляры, которые были сериализованы до того, как этот член был добавлен.

[Serializable]
public class A // Same class
{
    public string B { get; set; }
    [OptionalField] public string C { get; set; } // New property
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...