protobuf-net - 即使使用固定长度 byteArray 也应始终应用 OverwriteList

标签 protobuf-net

我已经阅读了有关 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);

    }

最佳答案

实际上,就您的情况而言,我认为最合适的解决方法是:

[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,由google设计,被设计为可追加和可合并。因此,对于多值数据(列表、数组等),规范行为是在末尾附加新值; OverwriteList 允许新值替换旧值 - 但另一种方法很简单:没有任何旧值。

作为不相关的注释; new Random() 可能会导致令人困惑的情况,其中在紧密循环中创建的一组对象具有相同值。如果这可能是一个问题,请考虑使用 static 实例,例如:

static readonly Random rand = new Random();

public Settings()
{
    AccessCode = new byte[6];
    Message = "hello";
    lock(rand)
    {
        rand.NextBytes(AccessCode);
    }
}

关于protobuf-net - 即使使用固定长度 byteArray 也应始终应用 OverwriteList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12295169/

相关文章:

c# - 如何找到我刚刚用 protobuf-net 反序列化的消息?

c# - protobuf.net 中的子类化

c# - 具有 ProtoBuf.Meta 接口(interface)的模仿 ProtoEnumAttribute

c# - protobuf-net:如何序列化 EventHandler

c++ - C++ 中的 Protobuf ParseDelimitedFrom 实现

c# - 尝试序列化 PropertyInfo 时引发异常

c# - 是否有必要在公共(public)方法上声明属性 [DataMember(Order=n)] ?

C# SSL 客户端消息未在服务器上打印

java - protobuff-net 可以与 protoc 2.4.1 一起使用吗