ProtoBuf-Net可以反序列化为扁平类吗?

时间:2011-07-12 22:11:57

标签: c# protobuf-net

protobuf-net使用嵌套的protobuf构造来支持继承。但是,是否可以将属性推送到与继承的“序列化”版本具有相同属性的平面目标类中?

请参阅下面的测试示例。不用说,对于这两个属性,Flat命名空间的结果都是null。


可能的解决方案:首先按照物业的基础将数据复制到flat.B中 注意:这不是首选选项。


using System;

namespace hierarchy
{
    using ProtoBuf;

    [ProtoContract]
    public class A
    {
        [ProtoMember(1)]
        public string prop1 { get; set; }
    }

    [ProtoContract]
    public class B : A
    {
        public B()
        {
        }

        [ProtoMember(1)]
        public string prop2 { get; set; }

        public override string ToString()
        {
            return "prop1=" + prop1 + ", prop2=" + prop2;
        }

    }
}

namespace flat
{
    using ProtoBuf;

    [ProtoContract]
    public class B
    {
        [ProtoMember(1)]
        public string prop1 { get; set; }

        [ProtoMember(2)]
        public string prop2 { get; set; }

        public override string ToString()
        {
            return "prop1=" + prop1 + ", prop2=" + prop2;
        }
    }
}

namespace TestProtoSerialization
{
    using ProtoBuf;
    using System.IO;

    public class Test2
    {
        public void Test()
        {
            var hb = new hierarchy.B();
            hb.prop1 = "prop1";
            hb.prop2 = "prop2";

            var ms = new MemoryStream();

            Serializer.Serialize<hierarchy.B>(ms, hb);

            var flatB = Serializer.Deserialize<flat.B>(ms);

            Console.WriteLine(hb.ToString());     // <----- Output: prop1=prop1, prop2=prop2  
            Console.WriteLine(flatB.ToString());  // <----- Output: prop1=, prop2=
        }
    }

    public class Program
    {
        private static void Main(string[] args)
        {
            var o2 = new Test2();
            o2.Test();
        }
    }

}

1 个答案:

答案 0 :(得分:2)

不直接,我不确定是否需要。也许我在示例中遗漏了一些内容......

要了解关键点 - 甚至忘记继承你已经破坏了合同 - 例如你的领域是1&amp; 1合1模型和1&amp; 2在另一个。

这取决于你的目标是什么;如果您只想推送数据,那么请确保您可以设置仅知道有关派生类型的RuntimeTypeModel(禁用自动配置并手动添加字段)。这将仅适用于派生类型(显然),但将按平面模型的预期输出数据:

var model = TypeModel.Create();
model.Add(typeof(B), false)
    .Add("prop1", "prop2");

然后使用model.Serialize等。

但是,在c#上编写平面转换方法或使用AutoMapper会更加明显。如果我的目标是从输出中删除继承,我将只使用上述内容,例如出于互操作性原因。