为什么没有setter的属性未序列化


101

我有一个可序列化的类,并且该类中的一个属性在Guidgetter中生成一个。该属性没有实现设置程序,在序列化过程中将被忽略。这是为什么,我总是必须实现一个setter才能序列化我的属性。

[Serializable]
public class Example
{
    [XmlAttribute("id")]
    public string Id
    {
        get
        {
             return Guid.NewGuid().ToString();
        }
    }
}

我尝试实现一个空的setter,它已正确序列化。

[Serializable]
public class Example
{
    [XmlAttribute("id")]
    public string Id
    {
        get
        {
             return Guid.NewGuid().ToString();
        }
        set {}
    }
}

更新

您能否指出我该如何定义其值永远不变或内部生成值的属性?


1
第二个示例正确地序列化了……但是,当您尝试对其进行反序列化时会发生什么呢?
LightStriker 2012年

试试YAXLib [++ ]
新浪Iravanian 2012年

3
仅供参考,XML序列化器将忽略[Serializable]
约翰·桑德斯

@JohnSaunders我没有意识到。
康斯坦丁·迪涅夫

Answers:


60

它的局限性在于XmlSerializer它不对只读属性进行序列化,您在第二个示例中所做的本质上是使它进行序列化的技巧,但是,如果以后需要对它进行反序列化,它是没有用的。

或者,您可以切换到使用DataContractSerializer,它更加灵活。


8
DataContractSerializer也需要设置器。这是一个限制,因为即使我们只能将其用于一种类型的操作(例如反序列化),但声明必须同时用于两种操作,否则序列化过程在尝试对一个值进行序列化时将不知道如何处理该值。 XML成对象。
ryadavilli 2012年

7
@ryadavilli标记为的任何内容[DataMember]都将使用进行序列化DataContractSerializer(是否为只读)。
詹姆斯

1
@James之所以写上面的内容,是因为尝试相同时出现一些编译时错误。现在,当我回到代码中并删除了setter时,似乎可以正常编译了。对于我来说,这很奇怪,可能是家庭作业,需要对此进行更多研究。
ryadavilli 2012年

3
终于找到了我困惑的根源。序列化不需要属性设置器。但是,如果属性没有设置器,则XML不会反序列化为对象。在那里,功课完成了。
ryadavilli 2012年

1
@ryadavilli是的,这只是实现的限制XmlSerializer,它依赖于公共设置方法。DataContractSerializer从这个意义上讲,它要聪明一些(可能使用反射将场景设置在幕后)。
詹姆斯

10

请参阅MSDN文档中的“ 介绍XML序列化 ”。其中包括:

可以序列化的项目

可以使用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接口 ”。


6

-的限制XMLSerializer-没有设置器的属性无法序列化。

但是您可以DataContractSerializer用来序列化private setter properties-

[DataMember]
public string Id
{
    get
    {
         return Guid.NewGuid().ToString();
    }
    private set {}
}

该属性应该被序列化为xml属性(请参阅原始帖子)。您的代码(DataMember属性)产生一个xml元素。据我所知,没有(干净的)方法可以告诉DataContractSerializer将属性转换为属性而不是元素。DataContractSerializer很不错,但您始终必须牢记此限制。
sth_Weird '16

2

如果要拥有私有设置器,并且对象可序列化/可反序列化,则意味着可以ISerializable,并创建一个类似于MyObject(SerializationInfo info,StreamingContext context)的构造函数。这里有一个例子


0

序列化属性用于序列化和反序列化对象。XmlSerializer将假定您不需要序列化没有设置器的任何属性。将字符串反序列化为对象时将使用Setter,因为需要创建对象的实例,然后使用Setter来填充属性值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.