[英]Protobuf-net surrogate class for BigInteger
我想在BigInteger值上使用protobuf-net。 因此,我编写了替代类,进行了测试并得到了结果
这是测试源:
using ProtoBuf;
using System;
using System.Numerics;
namespace BigIntegerSurrogate
{
[ProtoContract]
public class AA
{
[ProtoMember(1)]
public BigInteger Bi { get; set; }
}
[ProtoContract]
public class BigIntegerSurrogate
{
[ProtoMember(1)]
public byte[] BigIntegerBytes;
[ProtoConverter]
public static BigIntegerSurrogate Convert(BigInteger source)
{
var t = source.ToByteArray();
Console.WriteLine($"Convert from Source: {source.ToString()} => [{string.Join(",", t)}]");
return new BigIntegerSurrogate
{
BigIntegerBytes = t
};
}
[ProtoConverter]
public static BigInteger Convert(BigIntegerSurrogate surrogate)
{
if (surrogate == null || surrogate.BigIntegerBytes == null)
{
return BigInteger.Zero;
}
else
{
var bi = new BigInteger(surrogate.BigIntegerBytes);
Console.WriteLine($"Convert from Bytes: [{string.Join(",", surrogate.BigIntegerBytes)}] => {bi.ToString()}");
return bi;
}
}
}
class Program
{
static void Main(string[] args)
{
var model = ProtoBuf.Meta.RuntimeTypeModel.Default;
//model.Add(typeof(BigInteger), true);
model.Add(typeof(BigInteger), false).SetSurrogate(typeof(BigIntegerSurrogate));
var aa = new AA() { Bi = 100 };
byte[] aaSerialized;
using (var stream = new System.IO.MemoryStream())
{
Serializer.Serialize(stream, aa);
aaSerialized = stream.ToArray();
}
AA aa2;
using (var stream = new System.IO.MemoryStream(aaSerialized))
{
aa2 = Serializer.Deserialize<AA>(stream);
}
Console.WriteLine($"{aa2.Bi.ToString()}");
}
}
}
结果是:
Convert from Source: 100 => [100]
Convert from Source: 0 => [0]
Convert from Bytes: [0,100] => 25600
首先,protobuf调用期望值(= 100),但再次调用未知的零。
并在反序列化中使用100和0的混合数组调用convert()。
我有什么问题吗? 如果是这样,以二进制格式对BigInteger进行反序列化的正确方法是什么?
听起来好像第二次转换是反序列化期间的初始值,然后这会导致连接的字节数组。 一种快速的解决方法是在转换运算符中检查零,并始终分配一个空/空字节数组。 这将干净地连接在一起。 但是,“正确”的解决方法可能是在ProtoMemberAttibute
的字节数组上添加“覆盖列表”标志-这将确保替换内容而不是将其串联。 坦率地说,我很想同时做这两项。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.