带有继承的复杂类型的 protobuf-net 数组

发布于 2024-11-29 14:53:09 字数 3384 浏览 0 评论 0原文

我有一个层次结构,可以说 BaseClass <- DerivedClass 我想使用混合的 DerivedClass 和 BaseClass 对象序列化 BaseClass[] 数组
我使用 V2 源代码修订版 r438(2011 年 8 月 9 日)

伪代码: myArray = new BaseClass[] {new BaseClass(), new DerivedClass()};

我尝试了几种声明,但没有得到想要的结果:

[ProtoMember(1, AsReference = true, DynamicType = true)]
private BaseClass[] myArray;

->不会反序列化所有未设置的引用

[ProtoMember(1, AsReference = true, DynamicType = true)]
private object[] myArray;

-> deserailze,但数组类型从 BaseClass[] 更改为 object[]

有什么建议我如何才能恢复原来的 BaseClass[] 数组?

[编辑]单元测试:

namespace TechnologyEvaluation.Protobuf.ArrayOfBaseClassTest
{
    using System;
    using NUnit.Framework;
    using ProtoBuf;
    using ProtoBuf.Meta;

    [ProtoContract]
    class BaseClassArrayContainerClass
    {
        [ProtoMember(1, DynamicType = true)]
        public Base[] BaseArray { get; set; }
    }

    [ProtoContract]
    class ObjectArrayContainerClass
    {
        [ProtoMember(1, DynamicType = true)]
        public object[] ObjectArray { get; set; }

    }
    [ProtoContract]
    class Base
    {
        [ProtoMember(1)]
        public string BaseClassText { get; set; }
    }

    [ProtoContract]
    class Derived: Base
    {
        [ProtoMember(1)]
        public string DerivedClassText { get; set; }
    }

    [TestFixture]
    class ArrayOfBaseClassTests : AssertionHelper
    {
        [Test]
        public void TestObjectArrayContainerClass()
        {
            var model = CreateModel();
            var container = new ObjectArrayContainerClass();
            container.ObjectArray = this.CreateArray();
            var cloned = (ObjectArrayContainerClass) model.DeepClone(container);
            Expect(cloned.ObjectArray, Is.Not.Null);

            foreach (var obj in cloned.ObjectArray )
            {
                Expect(obj as Base, Is.Not.Null);
            }

            Expect(cloned.ObjectArray[1] as Derived, Is.Not.Null);
            Expect(cloned.ObjectArray.GetType(), Is.EqualTo(typeof(Base[])));

        }

        [Test]
        public void TestBaseClassArrayContainerClass()
        {
            var model = CreateModel();
            var container = new BaseClassArrayContainerClass();
            container.BaseArray = this.CreateArray();
            var cloned = (BaseClassArrayContainerClass) model.DeepClone(container);
            Expect(cloned.BaseArray, Is.Not.Null);

            foreach (var obj in cloned.BaseArray)
            {
                Expect(obj as Base, Is.Not.Null);
            }
            Expect(cloned.BaseArray[1] as Derived, Is.Not.Null);
            Expect(cloned.BaseArray.GetType(), Is.EqualTo(typeof(Base[])));
        }

        RuntimeTypeModel CreateModel()
        {
            RuntimeTypeModel model = RuntimeTypeModel.Create();

            model.Add(typeof(ObjectArrayContainerClass), true);
            model.Add(typeof(BaseClassArrayContainerClass), true);
            model.Add(typeof(Base), true);
            model[typeof(Base)].AddSubType(100, typeof(Derived));

            return model;
        }

        Base[] CreateArray()
        {
            return new Base[] { new Base() { BaseClassText = "BaseClassText" }, new Derived() { BaseClassText = "BaseClassText", DerivedClassText = "DerivedClassText" } };
        }
    }
}

I have an hierarchy, lets say BaseClass <- DerivedClass
I want to serialize a BaseClass[] array with mixed DerivedClass and BaseClass objects
I use V2 Sourcecode Revision r438 (Aug 9, 2011)

Pseudocode:
myArray = new BaseClass[] {new BaseClass(), new DerivedClass()};

I tried several declarations, but i don't get the desired result:

[ProtoMember(1, AsReference = true, DynamicType = true)]
private BaseClass[] myArray;

-> Wont deserialize all references are not set

[ProtoMember(1, AsReference = true, DynamicType = true)]
private object[] myArray;

-> deserailze, but array type changed from BaseClass[] to object[]

Any suggetions how i can get my original BaseClass[] array back?

[Edit] Unit Tests:

namespace TechnologyEvaluation.Protobuf.ArrayOfBaseClassTest
{
    using System;
    using NUnit.Framework;
    using ProtoBuf;
    using ProtoBuf.Meta;

    [ProtoContract]
    class BaseClassArrayContainerClass
    {
        [ProtoMember(1, DynamicType = true)]
        public Base[] BaseArray { get; set; }
    }

    [ProtoContract]
    class ObjectArrayContainerClass
    {
        [ProtoMember(1, DynamicType = true)]
        public object[] ObjectArray { get; set; }

    }
    [ProtoContract]
    class Base
    {
        [ProtoMember(1)]
        public string BaseClassText { get; set; }
    }

    [ProtoContract]
    class Derived: Base
    {
        [ProtoMember(1)]
        public string DerivedClassText { get; set; }
    }

    [TestFixture]
    class ArrayOfBaseClassTests : AssertionHelper
    {
        [Test]
        public void TestObjectArrayContainerClass()
        {
            var model = CreateModel();
            var container = new ObjectArrayContainerClass();
            container.ObjectArray = this.CreateArray();
            var cloned = (ObjectArrayContainerClass) model.DeepClone(container);
            Expect(cloned.ObjectArray, Is.Not.Null);

            foreach (var obj in cloned.ObjectArray )
            {
                Expect(obj as Base, Is.Not.Null);
            }

            Expect(cloned.ObjectArray[1] as Derived, Is.Not.Null);
            Expect(cloned.ObjectArray.GetType(), Is.EqualTo(typeof(Base[])));

        }

        [Test]
        public void TestBaseClassArrayContainerClass()
        {
            var model = CreateModel();
            var container = new BaseClassArrayContainerClass();
            container.BaseArray = this.CreateArray();
            var cloned = (BaseClassArrayContainerClass) model.DeepClone(container);
            Expect(cloned.BaseArray, Is.Not.Null);

            foreach (var obj in cloned.BaseArray)
            {
                Expect(obj as Base, Is.Not.Null);
            }
            Expect(cloned.BaseArray[1] as Derived, Is.Not.Null);
            Expect(cloned.BaseArray.GetType(), Is.EqualTo(typeof(Base[])));
        }

        RuntimeTypeModel CreateModel()
        {
            RuntimeTypeModel model = RuntimeTypeModel.Create();

            model.Add(typeof(ObjectArrayContainerClass), true);
            model.Add(typeof(BaseClassArrayContainerClass), true);
            model.Add(typeof(Base), true);
            model[typeof(Base)].AddSubType(100, typeof(Derived));

            return model;
        }

        Base[] CreateArray()
        {
            return new Base[] { new Base() { BaseClassText = "BaseClassText" }, new Derived() { BaseClassText = "BaseClassText", DerivedClassText = "DerivedClassText" } };
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文