2

我已经阅读了有关 protobuf 中字节数组处理的几个问题,只是想确保我做的事情正确。如果我忽略OverwriteList每次加载/保存字节的大小都会增加。如果您为该属性提供默认值,那么如果您使用数组或列表始终指定覆盖,那么正确的方法是什么?

[ProtoContract]
class Settings
{
    public Settings()
    {
        AccessCode = new byte[6];
        Message = "hello";
        Random r = new Random();
        r.NextBytes(AccessCode);
    }

    [ProtoMember(1, OverwriteList=true)]
    public byte[] AccessCode { get; set; }

    [ProtoMember(2)]
    public string Message { get; set; }
}

我正在使用来自 protobuf 的 Souce 2.0.0.569。

    static void Main()
    {
        using (MemoryStream ms = new MemoryStream())
        {
            Settings s = new Settings();
            Display(s);

            Serializer.Serialize<Settings>(ms, s);

            ms.Seek(0, SeekOrigin.Begin);

            Settings newSettings = Serializer.Deserialize<Settings>(ms);
            Display(newSettings);
        }
    }

    static void Display(Settings s)
    {
        Console.WriteLine("Access Code Length = {0} Message = {1}", s.AccessCode.Length, s.Message);

    }
4

1 回答 1

2

实际上,在您的情况下,我会说最合适的解决方法是:

[ProtoContract(SkipConstructor = true)]
class Settings
{
    public Settings()
    {
        AccessCode = new byte[6];
        Message = "hello";
        Random r = new Random();
        r.NextBytes(AccessCode);
    }

    [ProtoMember(1)]
    public byte[] AccessCode { get; set; }

    [ProtoMember(2)]
    public string Message { get; set; }
}

没有指定OverwriteList. 这将避免额外的冗余初始化步骤。

解释一下OverwriteList:由谷歌设计的protobuf被设计为可追加和可合并。因此,对于多值数据(列表、数组等),规范行为是在末尾附加新值;OverwriteList允许新值替换旧值 - 但另一种方法很简单:没有任何旧值。

作为不相关的说明;可能会导致在紧密循环中创建的一组对象具有相同new Random()的混乱场景。如果这可能是个问题,请考虑改用实例,例如:static

static readonly Random rand = new Random();

public Settings()
{
    AccessCode = new byte[6];
    Message = "hello";
    lock(rand)
    {
        rand.NextBytes(AccessCode);
    }
}
于 2012-09-06T08:40:26.570 回答