我们在序列化一个空列表时遇到了一些问题。 这里有一些使用 CF 2.0 的 .NET 代码
//Generating the protobuf-msg
ProtoBufMessage msg = new ProtoBufMessage();
msg.list = new List<AnotherProtobufMessage>();
// Serializing and sending throw HTTP-POST
MemoryStream stream = new MemoryStream();
Serializer.Serialize(stream, msg);
byte[] bytes = stream.ToArray();
HttpWebRequest request = createRequest();
request.ContentLength = bytes.Length ;
using (Stream httpStream = request.GetRequestStream())
{
httpStream.Write(bytes, 0, bytes.Length);
}
当我们尝试写入流时出现异常(bytes.length 超出范围)。 但是一个空列表的类型不应该是 0 字节,对吧(类型信息?)?
我们需要这种类型的发送,因为在 Response 中是来自服务器的消息给我们的客户端。
最佳答案
有线格式(由谷歌定义 - 不在我的控制范围内!)只发送项目的数据。它不区分空 列表和空 列表。因此,如果没有数据要发送 - 是的,长度为 0(这是一种非常节俭的格式;-p)。
Protocol Buffer 不包含在线路上的任何类型元数据。
这里的另一个常见陷阱是,您可能假设您的列表属性自动实例化为空,但它不会(除非您的代码这样做,可能在字段初始值设定项或构造函数中)。
这是一个可行的技巧:
[ProtoContract]
class SomeType {
[ProtoMember(1)]
public List<SomeOtherType> Items {get;set;}
[DefaultValue(false), ProtoMember(2)]
private bool IsEmptyList {
get { return Items != null && Items.Count == 0; }
set { if(value) {Items = new List<SomeOtherType>();}}
}
}
也许是 Hacky,但它应该可以工作。如果需要,您也可以丢失 Items
“set”,只需删除 bool
:
[ProtoMember(1)]
public List<SomeOtherType> Items {get {return items;}}
private readonly List<SomeOtherType> items = new List<SomeOtherType>();
[DefaultValue(false), ProtoMember(2)]
private bool IsEmptyList {
get { return items.Count == 0; }
set { }
}
关于c# - protobuf-net:序列化一个空列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2378666/