【问题标题】:How to serialize arrays?如何序列化数组?
【发布时间】:2012-05-09 06:01:13
【问题描述】:

症状:没有为类型定义序列化程序:System.Array

由于所有 C# 数组都继承自 Array 类,我认为这在 ProtoBuf-net 中是有效的

[ProtoMember(1)]
public Array SomeKindOfArray = new int[]{1,2,3,4,5};

[ProtoMember(2)]
public List<Array> SomeKindOfList = new List<Array>();

我应该向 RuntimeTypeModel 注册 Array 吗?

m.Add(typeof (Array), true);  // does not seem to help

尝试:

new int[]{1,2,3,4} // works

(object)new int[] { 1, 2, 3, 4 } // does not work

(Array)new int[] { 1, 2, 3, 4 } // does not work

另一种可能的解决方案(现在找不到 SO url):

有一个基类型类项目的列表。

包装每种类型。例如

class TheBase{}

class ArrayOfInt { public int[] value;}

然后将成为转换为包装器列表和从包装器列表转换的一种。有没有更简单的方法?

【问题讨论】:

    标签: c# protobuf-net


    【解决方案1】:

    protobuf-net 真的很想了解你正在序列化的数据;拥有Array 是不够的,因为它不能映射到任何 protobuf 定义。重复数据(从概念上讲,数组)在 protobuf 规范中具有非常简洁和非常具体的表示,这不允许在个人基础上说“[x]”的额外空间。在 protobuf 中,“of [x]”应该是已知的并提前修复

    所以:

    [ProtoMember(1)]
    public int[] AnIntegerArray {get;set;}
    
    [ProtoMember(2)]
    public Customer[] ACustomerArray {get;set;}
    

    会正常工作。但是Array 根本不起作用。

    根据它的重要性,可能还有其他选项,例如(您可能想要调整名称!):

    [ProtoContract]
    [ProtoInclude(1, typeof(DummyWrapper<int>)]
    [ProtoInclude(2, typeof(DummyWrapper<Customer>)]
    public abstract class DummyWrapper {
        public abstract Type ElementType {get;}
    }
    [ProtoContract]
    public class DummyWrapper<T> : DummyWrapper {
        [ProtoMember(1)]
        public T[] TheData {get;set;}
    
        public override Type ElementType {get { return typeof(T); } }
    }
    

    与:

    [ProtoMember(1)]
    public DummyWrapper TheData {get;set;}
    

    我怀疑(未经测试)会起作用。有了类,protobuf-net 可以使用一些额外的空间来实现继承(从技术上讲,protobuf 规范也不支持继承 - 这是 protobuf-net 挤入的 shim)。

    【讨论】:

    • 我喜欢这些名字。我将找到一种方法将它们整合到我的下一个项目中。它们将成为假人的包装器!
    • 对从更友好的 .net 转换为 protobuf-net 的好方法有什么想法吗?我在想一个或两个带有 if(obj is int[]) 语句列表的扩展方法可能会做到这一点。谢谢你的解释。
    • @sgtz 你能重新表述“从更友好的 .net 转换为 protobuf-net”吗?我没明白你的意思
    • 即。将 IEnumerable 转换为 List
    • @sgtz 好吧,这很棘手;通常我会说“您可以为此使用代理”,但Array 将首先遇到其他一些情况,尤其是内置列表处理。我的建议是:如果您尝试序列化您的主要对象模型并且它开始变得困难,那么:不要 - 编写一个看起来类似的 DTO 模型,但它可以很容易地序列化。
    【解决方案2】:

    你为什么不尝试像这样创建一个新的 ISerializable 对象

    [Serializable()]    
    public class ArrayOfInt : ISerializable 
    {
        public Array ....etc
    

    并从接口 ISerializable 覆盖 GetObjectData()

    【讨论】:

    • 因为问题明确提到了protobuf-net,它不使用ISerializable(但可以用于实现ISerializable
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-10
    • 2014-12-05
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多