C# 强制protobuf net序列化所有默认值

C# 强制protobuf net序列化所有默认值,c#,serialization,protobuf-net,C#,Serialization,Protobuf Net,我用protobuf-net序列化/反序列化了一个复杂的模型,我们有几个错误,这个“特性”没有序列化默认值 例如: [DataContract] class Foo{ public Foo(){ // Value forced by constructor this.Value = 1; } // Buggy, when Value is set to zero [DataMember(Order = 1)] public double Value {get

我用protobuf-net序列化/反序列化了一个复杂的模型,我们有几个错误,这个“特性”没有序列化默认值

例如:

[DataContract]
class Foo{
  public Foo(){
    // Value forced by constructor
    this.Value = 1;
  }

  // Buggy, when Value is set to zero
  [DataMember(Order = 1)]
  public double Value {get; set}
}
当Value=0时,protobuf-net不会对其进行序列化,但在反序列化过程中,构造函数会强制值为1(protobuf-net不会更改此值)

为了使其正常工作,我需要强制protobuf net序列化值,包括:

  // Works fine
  [DataMember(Order = 1, IsRequired = true)]
  public double Value {get; set}
但是,由于这个特性,我们已经有了bug,我们想强制整个模型的protobuf-net,而不是标记每个属性


可能吗?

是的,完全支持此功能。事实上,如果我被迫承认v1中的设计决策是错误的,那么隐含的零默认值就是其中之一——但是为了向后兼容,默认情况下会保留该行为。您要查找的是
RuntimeTypeModel.useInflicitsFaults
,默认情况下为
true

为了避免更改依赖v1行为的代码行为(通过
serializer.*
),您不能在默认型号上更改此功能,因此您需要做的是:

  • 定义您自己的模型/序列化程序实例
  • 在使用它之前,设置
    useFaults=false
  • 在序列化/反序列化代码中,使用此实例而不是
    序列化程序。*
  • 例如:

    private static readonly RuntimeTypeModel serializer;
    static MyType() { // your type-initializer for class MyType
        serializer = TypeModel.Create();
        serializer.UseImplicitZeroDefaults = false;
    }
    ... then when needed:
    serializer.Serialize(stream, obj);
    ...
    ObjType obj = (ObjType)serializer.Deserialize(stream, null, typeof(ObjType));
    

    将来我可能会考虑的另一种方法是允许使用汇编级属性;这将特别有助于任何使用“预编译器”(例如,针对移动设备或WinRT)的人——因此(只需大声思考):


    然后将应用于该程序集中的所有类型。只是一个想法。另一个明显的优点是,它可以与使用经典的
    序列化程序的代码一起工作。*
    API。

    我在Protobuf net v1中没有找到TypeModel而不是RuntimeTypeModel(在主干中找到)。有没有办法用protobuf v1实现这一点?@ghusse在v1中?没有。你想避免v2有什么特别的原因吗?我们正在一个稳定的产品中使用(并已发布)的组件的迁移。官方protobuf wiki仍然说v2是测试版。这是真的,还是我们可以相信它?@ghusse我更新了这一点;是的,据我所知和测试,v2是稳定的
    // this feature ***does not currently exist***
    [assembly:ProtoDefaults(UseImplicitZeroDefaults=false, SkipConstructor=true)]