序列化私有成员数据
我试图序列化一个对象到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未处理:无法生成临时类(结果= 1)。 错误CS0200:属性或索引器“MyObject.Id”不能被分配给 – 它是只读的
如果我将Id属性设置为public,则可以正常工作。 有人可以告诉我,如果我正在做什么,或者至less如果可能的话?
你可以使用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
并自己做所有事情,但至less可以使用XmlSerializer
。
您可以使用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。 其余的代码是一样的。
只读字段将不会使用XmlSerializer
序列化,这是由于readonly
关键字的性质
来自MSDN:
readonly关键字是可以在字段上使用的修饰符。 当一个字段声明包含一个只读修饰符时,声明引入的字段的赋值只能作为声明的一部分或者在同一个类的构造函数中出现。
所以…你几乎需要在默认构造函数中设置字段值…
在特定的序列化模式下不可能(请参阅其他解决方法的注释)。 如果你真的想保持你的序列化模式,你必须解决这个框架的限制。 看到这个例子
本质上,将属性标记为public
,但是如果在反序列化之外的任何时候访问,则抛出exception。