Измените автоматически реализованные свойства на обычные и десериализацию с помощью BinaryFormatter

У меня есть объект со свойством, реализованным как

public String Bla {get;set;} 

После изменения реализации на что-то вроде

private String _bla;

public String Bla
{
    get { return _bla; }
    set { _bla = value; } 
} 

при десериализации это свойство оказывается пустым.

у меня есть много сериализованных данных из старой реализации, и я хотел бы загрузить их с новой реализацией

есть ли способ изменить внедрение, чтобы оно было совместимо со старыми двоичными файлами?

ИЗМЕНИТЬ:

Некоторые люди могут столкнуться с той же проблемой, поэтому вот мое хакерское решение:

автоматически сгенерированные поля имеют соглашение об именах, которое является недопустимым кодом С#:

[CompilerGenerated]
private string <MyField>k__BackingField;

[CompilerGenerated]
public void set_MyField(string value)
{
    this.<MyField>k__BackingField = value;
}

[CompilerGenerated]
public string get_MyField()
{
    return this.<MyField>k__BackingField;
}

быстрое и грязное исправление для меня состояло в том, чтобы создать приватное резервное поле с именем xMyFieldxK__BackingField в исходном коде,

и исправить сериализованные двоичные данные, заменив все вхождения <MyField> на xMyFieldx перед десериализацией


person Dr. Wummi    schedule 05.12.2012    source источник
comment
Что вы подразумеваете под совместимостью со старыми двоичными файлами?   -  person Gregor Primar    schedule 05.12.2012
comment
@GregorPrimar: у меня есть много сериализованных данных из старой реализации, и я хотел бы загрузить их с новой реализацией   -  person Dr. Wummi    schedule 05.12.2012
comment
Я очень сомневаюсь, что вы можете сделать это с помощью двоичной десериализации. Вы должны использовать XmlSerializer, тогда вы сможете десериализовать и более старые версии.   -  person Gregor Primar    schedule 05.12.2012
comment
На самом деле нет никакой разницы между обеими реализациями. Компилятор создает код, очень похожий на вторую реализацию, если вы используете первую реализацию. Таким образом, у вас должна быть причина изменить код - например. контролировать доступ к собственности. Можете ли вы показать нам более подробную информацию о вашем коде? (Дополнительную информацию можно найти здесь: codeproject.com/ Статьи/266593/Как это работает в Csharp)   -  person Carsten    schedule 05.12.2012


Ответы (2)


Попробуйте реализовать ISerializable

    [SecurityCritical]
    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");

        info.AddValue("name of compiler generated field", _bla);
    }
person Henrik    schedule 05.12.2012
comment
Это решение, но оно должно быть ужасным при работе с большой кодовой базой. У меня есть идея, хотя ;p - person leppie; 05.12.2012
comment
это ужасно с большой кодовой базой, но это правильный путь. я обновил свой вопрос своими выводами - person Dr. Wummi; 06.12.2012

BinaryFormatter сериализует поля, а не свойства.

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

В противном случае, как заявил Хенрик, вам придется написать свою собственную десериализацию, см. этот вопрос для получения дополнительной информации

Вероятно, вы можете проверить информацию о десериализации, внедрив ISerializable и особый случай в этом поле.

person Paul Tyng    schedule 05.12.2012