c# - protobuf-net:序列化一个空列表

标签 c# .net serialization protobuf-net

我们在序列化一个空列表时遇到了一些问题。 这里有一些使用 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/

相关文章:

c# - Datagrid中弹出+分页时,弹出窗口消失,因为页面加载W,

c# - 字符串和字符串有什么区别?

c# - 更新数据源时刷新DataGridView

database - Sitecore - 将网站从一个安装转移到另一个

wcf - 将用 [DataContract] 装饰的对象放入 StateServer?

c# - 如何避免异常反序列化无效的枚举项?

C# .Trim 由于某种原因不工作

c# - 为什么 C# 似乎部分取消转义命令行参数?

c# - Xamarin MotionEventActions.Move 永远不会在自定义 View onTouch 事件中被命中?

c# - 为 WCF 服务启用 HTTPS 流量。将流量 http 更改为 https 的问题