DataContractSerializer的MSDN文档是否不正确?

时间:2017-03-13 15:54:41

标签: c# msdn datacontractserializer

MSDN documentation for DataContractSerializer包含以下声明:

  

只读字段,没有get或set方法的属性以及具有内部或私有set或get方法的属性未序列化。这些属性被忽略,并且不会抛出异常,除了只有get的集合。

但是,我刚刚创建了以下程序,它将readonly,get-only和private-set属性序列化得很好。我误解了某些内容,还是文档不正确?

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string saveFile = "save.xml";
            Foo originalFoo = new Foo();
            SaveState(originalFoo, saveFile);
            Foo restoredFoo = LoadState<Foo>(saveFile);
        }
        public static void SaveState(Object o, string saveFile)
        {
            DataContractSerializer serializer = new DataContractSerializer(o.GetType());
            using (var writer = XmlWriter.Create(saveFile))
                serializer.WriteObject(writer, o);
        }
        public static T LoadState<T>(string loadFile)
        {
            using (var stream = new FileStream(loadFile, FileMode.Open))
            {
                DataContractSerializer serializer = new DataContractSerializer(typeof(T));
                T obj = (T)serializer.ReadObject(stream);
                return obj;
            }
        }
    }

    [Serializable]
    public class Foo
    {
        private readonly int X;
        private int Y { get; }
        internal int Z { get; private set; }
        public Foo()
        {
            X = Y = Z = 10;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

您使用Serializable属性指示序列化程序序列化所有内容。来自文档:

  

将SerializableAttribute属性应用于某个类型时,默认情况下会对所有私有和公共字段进行序列化。您可以通过实现ISerializable接口来更精细地控制序列化,以覆盖序列化过程。

如果省略所有属性,则只序列化公共属性和字段,如文档中所述。例如,如果添加W属性:

public class Foo
{
    private readonly int X;
    private int Y { get; }
    internal int Z { get; private set; }


    public int W { get; set; }
    public Foo()
    {
        X = Y = Z = 10;
    }
}

生成的文件将包含:

<?xml version="1.0" encoding="utf-8"?>
<Foo xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/SO_Serializer">
    <W>15</W>
</Foo>

如果您将DataContract属性添加到班级,则只会标记标有DataMember的成员

答案 1 :(得分:0)

不,这不是不正确的!

只读字段,没有get或set方法的属性以及具有内部或私有set或get方法的属性未序列化。这些属性被忽略,并且不会抛出异常,除了只有get的集合。

  

应用SerializableAttribute属性,即使该类还实现了ISerializable接口来控制序列化过程。

     

将SerializableAttribute属性应用于某个类型时,默认情况下会对所有私有和公共字段进行序列化。您可以通过实现ISerializable接口来更精细地控制序列化,以覆盖序列化过程。

     

或者,您可以通过将NonSerializedAttribute属性应用于字段来从序列化中排除字段。如果可序列化类型的字段包含特定于特定环境的指针,句柄或某些其他数据结构,并且无法在不同环境中进行有意义的重构,则可能需要将NonSerializedAttribute属性应用于该字段。