C# 强制protobuf net序列化所有默认值
我用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
[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)]