BigInteger 的 Protobuf-net 代理 class

Protobuf-net surrogate class for BigInteger

我想要 BigInteger 值上的 protobuf-net。 所以,我写代理class,测试并得到结果

这是测试源:

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),但它再次调用未知零。

并且它在反序列化时调用 convert() 与 100 和 0 的串联数组。 所以,结果值是错误的。

我是不是有什么问题?如果是这样,用二进制格式(反)序列化 BigInteger 的正确方法是什么?

听起来第二个convert是反序列化时的初始值,这导致了一个串联的字节数组。一种快速修复可能是检查转换运算符中的零并始终分配一个 null/empty 字节数组。这将干净地连接起来。但是,"correct" 修复可能是在字节数组的 ProtoMemberAttibute 中添加 "overwrite list" 标志 - 这将确保替换而不是连接内容。坦率地说,我很想同时做这两件事。