C# 序列化私有成员数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/802711/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 01:48:29  来源:igfitidea点击:

Serializing private member data

c#.netxmlserializationserializable

提问by Jon Mitchell

I'm trying to serialize an object to XML that has a number of properties, some of which are readonly.

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

public Guid Id { get; private set; }

I have marked the class [Serializable] and I have implemented the ISerializable interface.

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

Below is the code I'm using to serialize my object.

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

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

Unfortunately it falls over on the first line with this message.

不幸的是,它落在了这条消息的第一行。

InvalidOperationException was unhandled: Unable to generate a temporary class (result=1). error CS0200: Property or indexer 'MyObject.Id' cannot be assigned to -- it is read only

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

If I set the Id property to public it works fine. Can someone tell me if I'm doing something, or at least if its even possible?

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

采纳答案by Marc Gravell

You could use DataContractSerializer(but note you can't use xml attributes - only xml elements):

您可以使用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);
        }
    }
}

Alternatively, you can implement IXmlSerializableand do everything yourself - but this works with XmlSerializer, at least.

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

回答by Stefan Steinegger

You could use the System.Runtime.Serialization.NetDataContractSerializer. It is more powerful and fixes some issues of the classic Xml Serializer.

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

Note that there are different attributes for this one.

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

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


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

Edit:

编辑:

Update based on Marc's comment: You should probably use System.Runtime.Serialization.DataContractSerializerfor your case to get a clean XML. The rest of the code is the same.

根据 Marc 的评论更新:您可能应该使用System.Runtime.Serialization.DataContractSerializer您的案例来获得干净的 XML。其余代码相同。

回答by flalar

Read only fields will not be serialized using the XmlSerializer, this is due to the nature of the readonlykeyword

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

From MSDN:

来自 MSDN:

The readonlykeyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.

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

So... you would pretty much need to set the fields value in the default constructor...

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

回答by jvenema

Its not possible with that particular serialization mode (see the other comments for workarounds). If you really want to leave your serialization mode as-is, you have to work around the framework limitations on this one. See this example

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

Esentially, mark the property public, but throw an exception if it's accessed at any time other than deserialization.

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