protobuf-net 不使用私有资源库序列化 C# 属性
本文关键字:资源库 序列化 属性 protobuf-net | 更新日期: 2023-09-27 18:32:52
我今天一直在和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
}
编辑:我正在使用带有 protobuf 2.0.0.666<</p>
这是隐式的默认值行为。最简单的解决方法可能是使用 IsRequired=true 标记 IsEmpty(在属性属性上)。
在这里找到答案: 反序列化时 C# protobuf-net 某些属性值始终为 -1
为了节省空间,protobuf 不会序列化值类型的默认值。在此示例中,bool
的 .NET 默认值为 false
。 默认构造函数将 IsEmpty
属性设置为 true
,并且由于我期望它具有的值与 .NET 默认值相同,protobuf 跳过保存该值,因此我从默认构造函数中获取值。
解决方法是将 IsRequired 设置为 TRUE,如 Marc 所说,或者对参数使用 [ProtoContract(10), DefaultValue(true)]
。