编程语言
首页 > 编程语言> > C#Protobuf-net:小数字字典:零不能正常往返

C#Protobuf-net:小数字字典:零不能正常往返

作者:互联网

我发现了protobuf-net中十进制零序列化/反序列化的一个奇怪的错误,想知道是否有人为此找到了一个好的解决方法,或者这实际上是一个功能.

鉴于上面的字典,如果我在linqpad中运行:

void Main()
{
    {
        Dictionary<string, decimal> dict = new Dictionary<string, decimal>();
        dict.Add("one", 0.0000000m);
        DumpStreamed(dict);
    }

    {
        Dictionary<string, decimal> dict = new Dictionary<string, decimal>();
        dict.Add("one", 0m);
        DumpStreamed(dict);
    }
}

public static void DumpStreamed<T>(T val)
{
    using (var stream = new MemoryStream())
    {
        Console.Write("Stream1: ");
        ProtoBuf.Serializer.Serialize(stream, val);
        foreach (var by in stream.ToArray())
        {
            Console.Write(by);
        }

        Console.WriteLine();
        Console.Write("Stream2: ");
        stream.Position = 0;
        var item = ProtoBuf.Serializer.Deserialize<T>(stream);
        using(var stream2 = new MemoryStream())
        {
            ProtoBuf.Serializer.Serialize(stream2, item);
            foreach (var by in stream2.ToArray())
            {
                Console.Write(by);
            }

        }
    }

    Console.WriteLine();
    Console.WriteLine("----");
}

我会得到两个不同的流:

第一次序列化:1091031111101011822414

第二次序列化:107103111110101180

(反序列化时,0.0000000m将转换为0).

我发现这是由于ReadDecimal中的这行代码:

 if (low == 0 && high == 0) return decimal.Zero;

有谁知道为什么只在反序列化期间归零而不是序列化?

或者在序列化/反序列化中对字典中的十进制零进行一致规范化或一致不规范化的任何解决方法?

解决方法:

是的;问题是这个好意但有潜在危害的一条线:

    if (low == 0 && high == 0) return decimal.Zero;

这忽略了检查signScale.它应该是:

    if (low == 0 && high == 0 && signScale == 0) return decimal.Zero;

我会调整下一个版本.

(编辑:我最终完全删除了该检查 – 其余的代码只是一些整数移位等,所以拥有“分支”可能比没有它更昂贵)

标签:c,decimal,protobuf-net
来源: https://codeday.me/bug/20190622/1262284.html