繁体   English   中英

适用于BigInteger的Protobuf-net代理类

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM