如何使用Protobuf-Net序列化接口对象集合

时间:2015-07-08 22:05:31

标签: c# serialization protobuf-net

我有以下类定义:

[ProtoInclude(2, typeof(Foo))]
public interface IFoo
{
    double Bar { get; }
}



[ProtoContract]
public class Foo : IFoo
{
    [ProtoMember(1)]
    private double _bar
    {
        get { return Bar / 10; }
        set { Bar = 10 * value; }
    }

    public double Bar { get; private set; }
}



[ProtoContract]
public class MyClass
{
    [ProtoMember(1, OverwriteList = true)]
    public IReadOnlyList<IFoo> Foos { get; private set; }
}

当我尝试使用protobuf-net序列化 MyClass 对象时,我得到异常:

System.InvalidOperationException:无法为:MyNamespace准备序列化程序。我的课   ----&GT; System.InvalidOperationException:没有为类型定义的序列化程序:MyNamespace.IFoo

就我而言,我知道存储在 MyClass.Foos 中的项目的具体类型是 Foo 。如何告诉protobuf在它看到类型 IFoo 的任何地方使用 Foo 类型?或者,如何将 Foo 作为可用于在集合中实现 IFoo 的类之一?

- 编辑 -

Sam的答案非常接近,以至于它揭示了这种方法的另一个问题。即,it is not possible to serialize a property of type IReadOnlyList<T> using protobuf-net。但是,有一个简单的解决方法,因为列表是在MyClass的构造函数中创建的。因此,MyClass可以更改为以下内容:

[ProtoContract]
public class MyClass
{
    [ProtoMember(1, OverwriteList = true)]
    private List<IFoo> MutableFoos { get; set; }

    public IReadOnlyList<IFoo> Foos
    {
        get { return MutableFoos; }
    }
}

但是, MyClass 的序列化仍然失败,并显示消息“ System.InvalidOperationException:找不到代理项的合适转换运算符:MyNamespace.IFoo / MyNamespace.Foo

1 个答案:

答案 0 :(得分:1)

我从来没有能够在序列化成员中使用接口类的地方工作。相反,我最终不得不将具体类作为列表成员类型。以下是最终对我有用的内容:

[ProtoContract]
public class MyClass
{
    [ProtoMember(1, OverwriteList = true)]
    private List<Foo> MutableFoos { get; set; }

    public IReadOnlyList<IFoo> Foos
    {
        get { return MutableFoos; }
    }
}

请注意,序列化成员中的类型为List<Foo>,而不是List<IFoo>。我从来没有想过如何让后者工作。