序列化私有成员数据

时间:2009-04-29 14:49:18

标签: c# .net xml serialization serializable

我正在尝试将对象序列化为具有许多属性的XML,其中一些属性是只读的。

public Guid Id { get; private set; }

我已经标记了[Serializable]类,我已经实现了ISerializable接口。

下面是我用来序列化对象的代码。

public void SaveMyObject(MyObject obj)
{
    XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
    TextWriter tw = new StreamWriter(_location);
    serializer.Serialize(tw, obj);
    tw.Close();
}

不幸的是,它会在第一行显示此消息。

  

InvalidOperationException未处理:   无法生成临时类(result = 1)。   错误CS0200:无法将属性或索引器“MyObject.Id”分配给 - 它是只读的

如果我将Id属性设置为public,则可以正常工作。有人可以告诉我,如果我正在做某事,或者至少是否可能吗?

4 个答案:

答案 0 :(得分:60)

您可以使用DataContractSerializer(但请注意,您不能使用xml属性 - 仅限xml元素):

using System;
using System.Runtime.Serialization;
using System.Xml;
[DataContract]
class MyObject {
    public MyObject(Guid id) { this.id = id; }
    [DataMember(Name="Id")]
    private Guid id;
    public Guid Id { get {return id;}}
}
static class Program {
    static void Main() {
        var ser = new DataContractSerializer(typeof(MyObject));
        var obj = new MyObject(Guid.NewGuid());
        using(XmlWriter xw = XmlWriter.Create(Console.Out)) {
            ser.WriteObject(xw, obj);
        }
    }
}

或者,您可以实施IXmlSerializable并自行完成所有操作 - 但这至少适用于XmlSerializer

答案 1 :(得分:6)

您可以使用System.Runtime.Serialization.NetDataContractSerializer。它功能更强大,修复了经典Xml Serializer的一些问题。

请注意,此属性有不同的属性。

[DataContract]
public class X
{
  [DataMember]
  public Guid Id { get; private set; }
}


NetDataContractSerializer serializer = new NetDataContractSerializer();
TextWriter tw = new StreamWriter(_location);
serializer.Serialize(tw, obj);

修改

根据Marc的评论进行更新:您应该使用System.Runtime.Serialization.DataContractSerializer来获取干净的XML。其余代码是相同的。

答案 2 :(得分:2)

只读字段不会使用XmlSerializer序列化,这是由于readonly关键字的性质

来自MSDN:

  

readonly 关键字是您可以在字段上使用的修饰符。当字段声明包含只读修饰符时,声明引入的字段的赋值只能作为声明的一部分或在同一类的构造函数中出现。

所以......你几乎需要在默认构造函数中设置字段值...

答案 3 :(得分:0)

使用该特定序列化模式无法实现(请参阅其他注释以了解解决方法)。如果您确实希望按原样保留序列化模式,则必须解决此问题的框架限制。见example

基本上,标记属性public,但如果在反序列化之外的任何时间访问它,则抛出异常。