代码之家  ›  专栏  ›  技术社区  ›  Paul Farry

是否应始终应用OverwriteList(即使使用FixedLength字节数组)

  •  2
  • Paul Farry  · 技术社区  · 12 年前

    我读过关于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);
    
        }
    
    1 回复  |  直到 12 年前
        1
  •  2
  •   Marc Gravell    12 年前

    事实上,在你的情况下,我认为最合适的解决方案是:

    [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 这将避免额外的冗余初始化步骤。

    解释 重写列表 :protobuf,由谷歌设计,设计为可追加和可合并。因此,对于多值数据(列表、数组等),规范行为是 追加 最后的新价值观; 重写列表 允许新值 代替 旧的——但另一种方法很简单:不要有任何旧的价值观。

    作为一个无关的音符; new Random() 可能导致混乱的场景,其中在紧密循环中创建的一组对象 完全相同的 价值观如果这可能是一个问题,请考虑使用 static 例如:

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