c# - 序列化 C# 不可变结构的最佳实践是什么?
问题描述
我通常将我的结构设为只读。然而,序列化库(例如DataContractSerializer
)期望序列化的字段或属性是读/写的。
所以我相信我的选择是:
- 让我的字段可写只是为了安抚序列化程序
- 为序列化目的创建代理对象
- 使用反射自动生成代理
- 通过尝试使用启发式或属性猜测适当的构造函数来自动生成序列化/反序列化函数。
在这种情况下,人们通常会怎么做?
解决方案
如果您像这样初始化 DataContractSerializer 就能够序列化只读字段
var serializer = new DataContractSerializer(
typeof(ToSerialize),
new DataContractSerializerSettings()
{
SerializeReadOnlyTypes = true
});
但是,如果您想反序列化具有只有 getter 的属性的类,这只会单向工作。所以你可以序列化,但不能反序列化这样的东西:
[DataContract]
public struct ToSerialize
{
public ToSerialize(string a)
{
PropertyToSerialize = "a";
}
[DataMember]
public string PropertyToSerialize { get; }
}
因此,要么向您的属性添加一个私有集,要么添加一个支持字段并使用 [DataMember] 属性对其进行标记。
[DataContract]
public struct ToSerialize
{
public ToSerialize(string a)
{
backingField = "a";
}
public string PropertyToSerialize => backingField;
[DataMember]
string backingField;
}
通过使用私有设置器,您很难更改对象的状态(您可能可以使用反射来完成)。因此,如果没有方法更改结构中的字段并且所有属性都有私有设置器,那么您的结构在技术上是不可变的。在你的情况下,我会选择一个私人二传手,它比玩反射更具可读性并且花费更少的精力。
推荐阅读
- ios - 如何使用单个自定义单元格用两个数组填充表格视图?
- angular - Angular:根据条件设置按钮文本
- php - Python中的wget无法下载我想要的文件
- javascript - 如何在电子应用弹出浏览器窗口中启用远程网页的 javascript
- xcode - 在 Xcode 上构建存档时如何修复找不到头文件?
- azure - passport-azure-ad / msal.js 和动态范围
- javascript - 我得到每个按钮的相同值
- html - 我的标题中有一个按钮,但在只有 1 个按钮后仍然显示 2 个按钮
- javascript - 如何在表格中创建下拉列表?
- javascript - 使用 Firestore 文档和集合数据