序列化 C# 不可变结构的最佳实践是什么?

What is the best practice for serializing C# immutable structs?

我通常将我的结构设为只读。但是,序列化库(例如 DataContractSerializer)期望序列化字段或属性为 read/write。

所以我认为我的选择是:

人们在这种情况下通常会做什么?

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,它比玩反射更易读,花费的精力更少。