75

我正在尝试将一个对象序列化为具有许多属性的 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

4 回答 4

64

您可以使用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至少适用于 .

于 2009-04-29T14:57:00.520 回答
6

你可以使用System.Runtime.Serialization.NetDataContractSerializer. 它更强大,并修复了经典 Xml 序列化器的一些问题。

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

[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。其余代码相同。

于 2009-04-29T14:51:53.997 回答
2

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

来自 MSDN:

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

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

于 2009-04-29T14:59:45.630 回答
0

使用特定的序列化模式是不可能的(有关变通方法,请参阅其他评论)。如果你真的想保持你的序列化模式不变,你必须解决这个框架的限制。看这个例子

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

于 2009-04-29T15:14:15.267 回答