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

本文关键字:对象 集合 接口 序列化 何使用 Protobuf-Net | 更新日期: 2023-09-27 18:01:55

我有以下类定义:

[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准备序列化器。MyClass——>系统。InvalidOperationException:没有为MyNamespace类型定义序列化器。IFoo

在我的例子中,我知道存储在MyClass中的项的具体类型。Foo等于Foo。我如何告诉protobuf在任何看到类型IFoo的地方使用类型Foo ?或者,我如何使它包括Foo作为一个类可用于实现集合中的IFoo ?

—EDIT—

Sam的答案非常接近,以至于它揭示了这种方法的另一个问题。也就是说,不可能序列化IReadOnlyList使用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".

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

在序列化成员中使用接口类的情况下,我始终无法使其正常工作。相反,我最终不得不将具体类作为列表成员类型。以下是最终对我有效的方法:

[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>。我一直不知道如何让后者工作。