gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 09:09:05 24 4
gpt4 key购买 nike

我有一个使用 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序列化,但是在反序列化过程中,构造函数强制Value为1(protobuf-net不会改变这个)。

为了让它工作,我需要强制 protobuf-net 序列化值,使用:

  // Works fine
[DataMember(Order = 1, IsRequired = true)]
public double Value {get; set}

但是,由于我们已经因为这个功能而出现错误,我们希望为整个模型强制使用 protobuf-net,而不是标记每个属性。

这可能吗?

最佳答案

是的,完全支持此功能。实际上,如果我被迫承认 v1 中的错误设计决策,隐式零默认值将是其中之一——但为了向后兼容,默认情况下会保留该行为。您正在寻找的是 RuntimeTypeModel.UseImplicitZeroDefaults,默认情况下为 true

为避免更改依赖于 v1 行为的代码的行为(通过 Serilaizer.*),您不能更改 默认 上的此功能模型,所以你需要做的是:

  1. 定义你自己的模型/序列化器实例
  2. 设置UseImplicitZeroDefaults = false使用它之前
  3. 在您的序列化/反序列化代码中,使用此实例而不是 Serializer.*

例如:

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)尤其有帮助 - 所以(只是大声思考):

// this feature ***does not currently exist***
[assembly:ProtoDefaults(UseImplicitZeroDefaults=false, SkipConstructor=true)]

这将适用于该程序集中的所有类型。只是一个想法。另一个明显的优势是它可以与使用经典 Serializer.* API 的代码一起工作。

关于c# - 强制 protobuf-net 序列化所有默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12295976/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com