C# DataContractSerializer的MSDN文档是否不正确?

C# DataContractSerializer的MSDN文档是否不正确?,c#,msdn,datacontractserializer,C#,Msdn,Datacontractserializer,包含以下语句: 只读字段、没有get或set方法的属性以及具有内部或私有set或get方法的属性不会序列化。这些属性将被忽略,并且不会引发异常,只有get-only集合除外 但是,我刚刚创建了以下程序,它可以很好地序列化readonly、get only和private set属性。我是误解了什么,还是文档不正确 using System; using System.IO; using System.Runtime.Serialization; using System.Xml; namesp

包含以下语句:

只读字段、没有get或set方法的属性以及具有内部或私有set或get方法的属性不会序列化。这些属性将被忽略,并且不会引发异常,只有get-only集合除外

但是,我刚刚创建了以下程序,它可以很好地序列化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;
        }
    }
}
使用系统;
使用System.IO;
使用System.Runtime.Serialization;
使用System.Xml;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
string saveFile=“save.xml”;
Foo originalFoo=新Foo();
SaveState(originalFoo,saveFile);
Foo restoredFoo=LoadState(保存文件);
}
公共静态void SaveState(对象o,字符串saveFile)
{
DataContractSerializer serializer=新的DataContractSerializer(o.GetType());
使用(var writer=XmlWriter.Create(saveFile))
serializer.WriteObject(writer,o);
}
公共静态T加载状态(字符串加载文件)
{
使用(var stream=newfilestream(loadFile,FileMode.Open))
{
DataContractSerializer serializer=新的DataContractSerializer(typeof(T));
T obj=(T)serializer.ReadObject(流);
返回obj;
}
}
}
[可序列化]
公开课Foo
{
私有只读INTX;
私有整数Y{get;}
内部int Z{get;private set;}
公共食物(
{
X=Y=Z=10;
}
}
}

不,没有错

只读字段、没有get或set方法的属性以及具有内部或私有set或get方法的属性不会序列化。这些属性将被忽略,并且不会引发异常,只有get-only集合除外

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

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

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

您使用了指示序列化程序序列化所有内容的属性。从文档中:

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

如果对所有属性进行ommit,则只序列化公共属性和字段,如文档中所述。例如,如果添加
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>

15

如果将
DataContract
属性添加到类中,则只有标有
DataMember
的成员才会被序列化

您使用了
Serializable
属性,这意味着
序列化所有内容
文档页面看起来不完整。可以找到更完整的文档,其中说明支持的类型包括使用SerializableAttribute属性标记的类型。.NET Framework基类库中包含的许多类型都属于这一类。DataContractSerializer完全支持.NET Framework远程处理、BinaryFormatter和SoapFormatter使用的此序列化编程模型,包括对ISerializable接口的支持。您提供的信息非常有指导意义。非常感谢。然而,我仍然认为MSDN文档充其量只是误导。这表明没有办法序列化只读属性,这根本不是真的。它没有提到
[Serializable]
属性,让人相信没有解决这个缺点的方法。更糟糕的是,您提供给文档的链接增加了混乱,因为它说具有该属性的类“无法继承”。然而,我创建一个继承自
Foo
Bar
类时没有遇到任何问题,这两个类都是序列化的。他们说如果你使用适当的属性会发生什么。不过,您使用了泛型的
Serializable
属性,其含义是“序列化所有内容”。@kmote no,它表示
SerializableClass
不能被继承。不能,因为它是密封的谢谢你对SerializableClass的澄清。我的错误。至于你之前的评论,你提到了“适当的属性”。您是说使用
[Serializable]
不适合DataContractSerializer吗?这是否意味着这是我应该避免的黑客行为?如果该属性不受支持,那么您的参数是有意义的。但如果是这样,那么文档至少应该提到它,你不认为吗?我否决了你,因为你说我错了,尽管我发布了代码来证明我错了,而你除了我在原始帖子中引用的声明之外,没有提供任何见解。@K注意,这不是否决的理由,否则,人们可能会对您使用的属性不是用于定义数据协定这一事实提出异议,并将其应用于他们。@Pa