序列化 xml 文件是否必须使用私有字段?

Are private fields mandatory for serialising xml files?

在我所有关于 xml 序列化的学习中,示例显示使用带有私有后台存储字段的 public 属性。

但后来我发现了这个:

https://blog.udemy.com/csharp-serialize-to-xml/

我还了解到,在 C# 3.0 中,您并不总是需要后备存储字段,因为它是在幕后完成的。

那么我应该简化我的代码并遵循 link 并只使用 public 属性吗?

XmlSerializer 完全不需要显式私有支持字段,它只能序列化 public 字段和属性。只要支持字段是私有的,XmlSerializer 就无法检测它是由编译器显式创建还是秘密创建,如 docs:

中所述

When you declare [an auto-implemented property], the compiler creates a private, anonymous backing field that can only be accessed through the property's get and set accessors.

如果您仅使用 XmlSerializer(或 with DefaultContractResolver.IgnoreSerializableAttribute = true,这是默认设置)进行序列化,请直接使用自动实现的属性简化您的 类。

但是,请注意,自动实现的属性在 [Serializable] 中效果不佳。当你用这个属性标记一个类型时,你表明它可以通过序列化它的 internal state -- 它的 public 和 private fields1——而不是它的外部状态——它的public属性。尽管此属性被 XmlSerializer 完全忽略,但某些其他序列化程序支持它,包括 DataContractSerializerDataContractJsonSerializerBinaryFormatter。如果将属性添加到具有自动实现属性的类型,秘密 "anonymous" 支持字段的名称可以开始出现在由那些序列化程序创建的序列化流中。这有时会导致诸如以下问题中的问题:

  • Is there a way to make DataContractSerializer output cleaner XML?.

  • How to remove k__BackingField from json when Deserialize.

  • DataContractJsonSerializer generating Ghost string to JSON keys?.

  • .

  • .

因此,如果您使用自动实现的属性,我的建议是从您的类型中删除 [Serializable] 属性。您可能不需要它,数据协定序列化在没有它的情况下工作得更好,无论如何,它的使用在 .NET Core 中已被弃用,如 and here. (Though reportedly binary serialization is getting implemented to some extent in .NET Core 2.0, see here 所示以获取详细信息。)


1 为什么是字段?在 .Net 1.1 时间框架内,仍然存在关于序列化私有状态是否比序列化 public 状态更可取的争论。这不再争论,首选 public 状态(或某些数据契约指定的状态)的序列化。