Почему свойства без сеттера не сериализованы
У меня есть сериализуемый класс, и одно из свойств в моем классе генерирует Guid
в getter. Свойство не реализует сеттер и игнорируется при сериализации. Почему это и я всегда должен реализовать сеттер, чтобы мое свойство было сериализовано.
[Serializable]
public class Example
{
[XmlAttribute("id")]
public string Id
{
get
{
return Guid.NewGuid().ToString();
}
}
}
Я попробовал реализовать пустой сеттер, и он получил сериализацию правильно.
[Serializable]
public class Example
{
[XmlAttribute("id")]
public string Id
{
get
{
return Guid.NewGuid().ToString();
}
set {}
}
}
Обновление
Можете ли вы указать, как определить свойства, значения которых никогда не изменяются, или значения, которые внутреннее значение генерируется?
Ответы
Ответ 1
Это ограничение XmlSerializer
не сериализует свойства только для чтения, то, что вы сделали в своем втором примере, по сути является хаком, чтобы заставить его сериализоваться, однако это бесполезно, если вам нужно его десериализовать позже.
В качестве альтернативы вы можете переключиться на DataContractSerializer, это более гибко.
Ответ 2
См. " Знакомство с сериализацией XML" в документации MSDN. Среди прочего, он говорит:
Элементы, которые могут быть сериализованы
Следующие элементы могут быть сериализованы с использованием класса XmlSerializer:
Public read/write properties and fields of public classes.
Classes that implement ICollection or IEnumerable.
Примечание:
Only collections are serialized, not public properties.
XmlElement objects.
XmlNode objects.
DataSet objects.
Кроме того, см. "Почему для класса XML-Serializable нужен конструктор без параметров"
Кроме того, IXmlSerializable
В дополнение к вышеуказанным типам, которые могут быть сериализованы с помощью Сериализатора XML, любой тип, который реализует интерфейс IXmlSerializable, может быть сериализован и десериализован. В частности, это означает, что типы XElement и XDocument могут быть сериализованы.
См. " IXmlSerializable Interface".
Ответ 3
Ограничение XMLSerializer
- Свойства без сеттера не могут быть сериализованы.
Но вы можете использовать DataContractSerializer
для сериализации private setter properties
-
[DataMember]
public string Id
{
get
{
return Guid.NewGuid().ToString();
}
private set {}
}
Ответ 4
если вы хотите иметь частные сеттеры, и чтобы объект был сериализуемым/десериализуемым, impliment ISerializable и создать конструктор, такой как MyObject (информация SerializationInfo, контекст StreamingContext). Пример приведен здесь.
Ответ 5
Атрибуты сериализации используются для сериализации и десериализации объектов.
XmlSerializer предположит, что вам не нужно сериализовать любое свойство, которое не имеет сеттера.
Сеттер будет использоваться при десериализации строки в объект, поскольку экземпляр объекта должен быть создан, а затем установщик будет использоваться для заполнения значения свойства.