Сначала фиксированный код, затем ответы на ваши вопросы:
public class Foo {
public Foo() : this("") {}
public Foo (string name) {
Name1 = name;
Name2 = name;
}
// note only this will be serialized
public string Name1 { get; private set; }
// this won't
private string Name2;
}
или в 3.0:
[DataContract]
class Foo {
public Foo (string name) {
Name1 = name;
Name2 = name;
}
[DataMember]
public string Name1 { get; private set; }
[DataMember]
private string Name2;
}
(и используйте DataContractSerializer
вместо XmlSerializer
)
XmlSerializer не является универсальным. Я должен привести от объекта к объекту (де) сериализации.
Это характерно для сериализаторов. У меня есть свой собственный сериализатор, и первоначально я сделал сделать его полностью универсальным. И это оказалось большой ошибкой дизайна. Огромный. Нет, серьезно. В настоящее время я переписываю каждую строку кода, чтобы отключить ее.
Просто; Сериализаторы обычно предполагают некоторый уровень отражения (для кода или для фактической работы, в зависимости от реализации). Отражение и дженерики не очень хорошо играют, особенно на некоторых платформах, таких как WCF. Выполнение финального приведения вашего кода - это честный компромисс. У меня есть число записей в блоге, если вы действительно хотите ...
Каждая собственность должна быть полностью публичной.
Это действительно ограничение XmlSerializer
(хотя список / коллекция без с установщиком в порядке, он выбросит , если у вас есть общедоступный набор get и private). Кроме того, тип должен быть открытым и иметь конструктор без параметров.
Почему мы не просто используем Reflection для доступа к частным сеттерам?
Для производительности XmlSerializer
строит сборку на лету, чтобы делать то, что вы хотите. Он не имеет автоматического доступа к внутренностям вашего кода. Для информации я делаю нечто подобное, но я предлагаю 2 уровня генерации; полностью статический (в развертываемой dll), который затем работает только с открытыми членами или в памяти, которая может по-прежнему обращаться к закрытым членам. Я думаю, что они хотели остановиться только на 1 модели, которая имеет смысл - и им нужен был «sgen», который диктует первую модель.
Закрытые поля нельзя сериализовать. Я хотел бы украсить приватные поля атрибутом, чтобы XmlSerializer включал их.
Затем используйте DataContractSerializer
, который будет сериализовать любого участника (включая частного), помеченного [DataMember]
.