序列化 C# 不可变结构的最佳实践是什么?
What is the best practice for serializing C# immutable structs?
我通常将我的结构设为只读。但是,序列化库(例如 DataContractSerializer
)期望序列化字段或属性为 read/write。
所以我认为我的选择是:
- 使我的字段可写以安抚序列化程序
- 为序列化目的创建代理对象
- 使用反射自动生成代理
- 通过尝试猜测一个自动生成 serialization/deserialization 函数
使用启发式或属性的适当构造函数。
人们在这种情况下通常会做什么?
DataContractSerializer 能够序列化只读字段,如果你像这样初始化它
var serializer = new DataContractSerializer(
typeof(ToSerialize),
new DataContractSerializerSettings()
{
SerializeReadOnlyTypes = true
});
但是如果你想用一个只有 getter 的 属性 反序列化一个 class,这只能单向工作。所以你可以序列化,但不能像这样反序列化:
[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;
}
通过使用私有 setters,你很难改变对象的状态(你可以使用反射来做到这一点)。因此,如果没有方法更改您的结构中的字段并且所有属性都有私有 setter,那么您的结构在技术上是不可变的。在你的情况下,我会选择私有 setter,它比玩反射更易读,花费的精力更少。
我通常将我的结构设为只读。但是,序列化库(例如 DataContractSerializer
)期望序列化字段或属性为 read/write。
所以我认为我的选择是:
- 使我的字段可写以安抚序列化程序
- 为序列化目的创建代理对象
- 使用反射自动生成代理
- 通过尝试猜测一个自动生成 serialization/deserialization 函数 使用启发式或属性的适当构造函数。
人们在这种情况下通常会做什么?
DataContractSerializer 能够序列化只读字段,如果你像这样初始化它
var serializer = new DataContractSerializer(
typeof(ToSerialize),
new DataContractSerializerSettings()
{
SerializeReadOnlyTypes = true
});
但是如果你想用一个只有 getter 的 属性 反序列化一个 class,这只能单向工作。所以你可以序列化,但不能像这样反序列化:
[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;
}
通过使用私有 setters,你很难改变对象的状态(你可以使用反射来做到这一点)。因此,如果没有方法更改您的结构中的字段并且所有属性都有私有 setter,那么您的结构在技术上是不可变的。在你的情况下,我会选择私有 setter,它比玩反射更易读,花费的精力更少。