C # сериализует приватный член класса - PullRequest
33 голосов
/ 30 ноября 2010
class Person
{
    public string m_name;
    private int m_age; // << how do I serialize the darn little rat?
}

Простой вопрос, но при попытке ответить на него возникает большой беспорядок.
Все предлагают использовать общедоступный метод получения / установки, но мое приложение слишком велико, и создание метода получения / установки для каждого участника вызовет проблемы с поддержкой.

Я вынужден создать собственную сериализацию здесь или есть магический атрибут для таких членов?
Как я сериализирую частных участников класса?

Редактировать # 1 :
Ок, все, извините за неясность, я немного расстроился, когда написал этот вопрос, прошло несколько часов после попытки найти решение.
Во всяком случае, вот больше фактов:
1. Я пытаюсь XML сериализовать этот класс. В настоящее время я использую System.Xml.Serialization.XmlSerializer.
2. Я сериализуюсь в XML, чтобы иметь совместимость версий , что, насколько я понимаю, двоичный файл не предлагает мне этого.
3. Я надеялся, что есть определенный атрибут , такой как :

class Person
{
    public string m_name;
    [SerializeThat(ElementName="Age")]
    private int m_age; // << how do I serialize the darn little rat?
}

ИЛИ (продолжение факта # 3) атрибута , который идет в классе , который будет выглядеть следующим образом:

[Serializable(DoPrivate = true, DoProtected = true)]
class Person
{
    public string m_name;
    private int m_age; // << how do I serialize the darn little rat?
}

Теперь, что я могу сделать, чтобы достичь этого?

Ответы [ 7 ]

17 голосов
/ 30 ноября 2010

Исходя из предположения о опечатке, я бы хотел перенаправить вас на эту статью SO , где решение состоит в том, чтобы использовать DataContractSerializer вместо.

8 голосов
/ 30 ноября 2010

Если вы используете BinaryFormatter, он будет использоваться для личных частей вашего класса.

Отметьте каждый свой класс с помощью [Serializable], иначе вы не уйдете далеко ...

Также посмотрите: Почему для сериализации объекта требуется сериализуемый атрибут

Так как вам нужен XML, возможно, вы можете справиться с этим с помощью SoapFormatter. Увидеть это .

По поводу совместимости версии: я использую BinaryFormatter и у меня нет проблем с обновлением схемы. Попробуйте, пожалуйста: вы можете обрабатывать изменения схемы самостоятельно, мы просто заменяем нулевые указатели, пропущенные Deserialize, соответствующими конструкциями по умолчанию. Если вам действительно не нужны функции, предоставляемые XML, переходите на двоичный код - вы никогда не оглянетесь назад.

Кроме того, еще один EDIT:

BF с готовностью разрешит все ваши множественные ссылки, поэтому он не будет создавать несколько экземпляров одной и той же ссылки снова и снова. Думаю, вы не получите этого с XmlSerializer - очевидно, что в нем нет места для хранения этой информации.

Пример:

class Data
{
    int a;
}

class ManyData
{
    Data d1;
    Data d2;
}

...

ManyData md=new ManyData();
md.d1=new Data();
md.d2=md.d1;

Попробуйте сериализовать / десериализовать md с несколькими альтернативами ...

7 голосов
/ 30 ноября 2010

Не знаю, можете ли вы использовать DataContract.Но с этим вы могли бы написать:

[DataContract]
class Person
{
    [DataMember]
    public string m_name;

    [DataMember]
    private int m_age;
}

Преимущество DataContract в том, что вы можете сериализовать приватные поля и ваш класс не нуждается в конструкторе по умолчанию.

5 голосов
/ 30 ноября 2010

Какой сериализатор вы сейчас используете?Почти все должны работать с этим.Но публичные поля * - это * плохая идея.XmlSerializer и JavaScriptSerializer будут игнорировать частных участников.DataContractSerializer и protobuf-net могут иметь дело с частными участниками.BinaryFormatter обрабатывает полей (открытый или закрытый), но по многим причинам не является хорошей идеей IMO.

2 голосов
/ 30 ноября 2010
0 голосов
/ 01 декабря 2018

Используйте IXmlSerializable интерфейс и поля управления, которые вы хотите сериализовать:

public interface IXmlSerializable
{
    XmlSchema GetSchema();
    void ReadXml(XmlReader reader);
    void WriteXml(XmlWriter writer);
}
0 голосов
/ 30 ноября 2010

Вам лучше написать собственный сериализатор

http://msdn.microsoft.com/en-us/library/system.runtime.serialization.iserializable.aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...