protobuf-net 不使用私有设置器序列化 C# 属性
Posted
技术标签:
【中文标题】protobuf-net 不使用私有设置器序列化 C# 属性【英文标题】:protobuf-net not serializing C# properties with private setters 【发布时间】:2013-09-25 21:46:15 【问题描述】:我今天一直在捣鼓 protobuf-net,遇到了一个奇怪的情况。下面的代码没有按预期反序列化。最后两次反序列化尝试成功,但不正确。反序列化对象的 IsEmpty 设置为 true
,而实际上它应该设置为 false
。我已经能够使用私有设置器获取属性以进行序列化就好了,但是这个行为不正确。跟链式默认构造函数有关系吗?
class Program2
static void Main(string[] args)
var comp = new FooComparer();
// this deserializes fine. woot!
using (var ms = new MemoryStream())
Console.WriteLine("Serializing an empty Foo");
var args1 = new Foo();
Serializer.Serialize(ms, args1);
ms.Position = 0;
var result = Serializer.Deserialize(ms);
Console.WriteLine("Serialization successful: 0", comp.Equals(args1, result));
Console.WriteLine();
// this deserializes incorrectly
using (var ms = new MemoryStream())
Console.WriteLine("Serializing a Foo with just a string");
var args1 = new Foo("576000BJ1");
Serializer.Serialize(ms, args1);
ms.Position = 0;
var result = Serializer.Deserialize(ms);
Console.WriteLine("Serialization successful: 0", comp.Equals(args1, result));
Console.WriteLine();
// this deserializes incorrectly
using (var ms = new MemoryStream())
Console.WriteLine("Serializing a Foo with an int");
var args1 = new Foo(42);
Serializer.Serialize(ms, args1);
ms.Position = 0;
var result = Serializer.Deserialize(ms);
Console.WriteLine("Serialization successful: 0", comp.Equals(args1, result));
Console.WriteLine();
Console.WriteLine("Got dat 190% serialization");
[ProtoContract]
class Foo
private Foo(bool isEmpty, string fooString, int? fooInt)
this.IsEmpty = isEmpty;
this.FooString = fooString;
this.FooInt = fooInt;
public Foo() : this(true, null, null)
public Foo(string foo) : this(false, foo, null)
public Foo(int foo) : this(false, null, foo)
[ProtoMember(10)] public bool IsEmpty get; private set;
[ProtoMember(20)] public string FooString get; private set;
[ProtoMember(30)] public int? FooInt get; private set;
class FooComparer : IEqualityComparer
public bool Equals(Foo x, Foo y)
return (x == null && y == null) ||
(x != null && y != null &&
x.IsEmpty == y.IsEmpty &&
String.Equals(x.FooString, y.FooString, StringComparison.Ordinal) &&
x.FooInt == y.FooInt);
public int GetHashCode(Foo obj) return 1; // don't care about this
编辑: 我正在使用 .NET 3.5 和 protobuf 2.0.0.666
【问题讨论】:
【参考方案1】:这是隐含的默认值行为。最简单的解决方法可能是将 IsEmpty 标记为 IsRequired=true(在属性属性上)。
【讨论】:
【参考方案2】:在这里找到答案:c# protobuf-net when deserialize the some property value always is -1
为了节省空间,protobuf 不会序列化值类型的默认值。
在此示例中,bool
的 .NET 默认值为 false
。默认构造函数将IsEmpty
属性设置为true
,并且由于我期望它具有的值与.NET 默认值相同,protobuf 跳过保存该值,因此我从默认构造函数中获取值。
修复方法是将 IsRequired 设置为 TRUE,就像 Marc 所说的那样,或者在参数上使用 [ProtoContract(10), DefaultValue(true)]
。
【讨论】:
以上是关于protobuf-net 不使用私有设置器序列化 C# 属性的主要内容,如果未能解决你的问题,请参考以下文章
使用 protobuf-net 为 Windows 商店应用程序序列化私有成员
Protobuf-net / NetCore2:反序列化忽略带注释的私有字段
protobuf-net 使用啥基本序列化器来输出字节数组?
为啥我的代码中的 protobuf-net 反序列化器比流式读取 csv 慢得多