代码之家  ›  专栏  ›  技术社区  ›  cdiggins

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

  •  0
  • cdiggins  · 技术社区  · 6 年前

    DataContractSerializer )预期序列化的字段或属性是读/写的。

    因此,我认为我的选择是:

    • 使我的字段可写只是为了安抚序列化程序
    • 为序列化目的创建代理对象
    • 使用反射自动生成代理
    • 通过尝试猜测错误自动生成序列化/反序列化函数 使用启发式或属性的适当构造函数。

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   Alexei Levenkov    6 年前

    如果您像这样初始化DataContractSerializer,它可以序列化只读字段

    var serializer = new DataContractSerializer(
           typeof(ToSerialize),
           new DataContractSerializerSettings() 
           { 
              SerializeReadOnlyTypes =  true
           });
    

    [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;
    }
    

    通过使用私有setter,您很难更改对象的状态(您可能可以使用反射进行更改)。因此,如果没有方法更改结构中的字段,并且所有属性都有私有setter,那么结构在技术上是不可变的。在你的情况下,我会选择一个私人二传,它比使用反射更具可读性,花费更少的精力。