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