Protobuf-net动态类型数组 [英] Protobuf-net dynamictype array

查看:106
本文介绍了Protobuf-net动态类型数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不会使用Protobuf-net进行序列化,并且此代码段会出现以下错误:

I wont to do some serialization with Protobuf-net and getting folowing error for this code snippet:

错误:

动态类型不是合同类型:TestType []

Dynamic type is not a contract-type: TestType[]

摘要:

using System.IO;
namespace QuickStart
{
    class Program
    {
        static void Main()
        {
            //FileAccess.ShowFileAccess();
            //Sockets.ShowSockets();

            var dto = new DataTransferType
            {
                ProtoDynamicProperty = new TestType[]
                {
                    new TestType {UselessProperty="AAA"},
                    new TestType{UselessProperty="BBB"},
                    new TestType{UselessProperty="CCC"}
                }
            };

            using (MemoryStream testStream = new MemoryStream())
            {
                ProtoBuf.Serializer.SerializeWithLengthPrefix(testStream, dto, ProtoBuf.PrefixStyle.Base128);
            }
        }


    }
    [ProtoBuf.ProtoContract]
    struct TestType
    {
        [ProtoBuf.ProtoMember(1)]
        public string UselessProperty { get; set; }
    }

    [ProtoBuf.ProtoContract]
    class DataTransferType
    {
        [ProtoBuf.ProtoMember(1, DynamicType = true)]
        public object ProtoDynamicProperty { get; set; }
    }
}

为什么会发生这种情况?我正在使用2.0.0.651 build

Any ideas why this happens? I`m using 2.0.0.651 build

推荐答案

用于protobuf-net的以前的项目站点:

DynamicType-存储具有类型的其他Type信息(默认情况下,它包括AssemblyQualifiedName,尽管这可以由用户控制).这样就可以序列化弱模型,即将object用于属性成员,但是当前仅限于 contract 类型(不是基本类型),并且不适用于具有继承性的类型(这些类型可能会在以后取消限制).与AsReference一样,它使用非常不同的布局格式.

DynamicType - stores additional Type information with the type (by default it includes the AssemblyQualifiedName, although this can be controlled by the user). This makes it possible to serialize weak models, i.e. where object is used for property members, however currently this is limited to contract types (not primitives), and does not work for types with inheritance (these limitations may be removed at a later time). Like with AsReference, this uses a very different layout format.

那么,合约类型到底是什么意思?如上所述,原始类型不是合同类型,仅此而已吗?来自 Protobuf-net:非官方手册:类型序列化的形式在protobuf-net中:

So, what exactly is meant by a contract type? As stated, primitive types are not contract types, but is that all? From Protobuf-net: the unofficial manual: Forms of type serialization in protobuf-net:

我要说的是protobuf-net在逐个类型的基础上(不包括原始类型)支持五种基本的[反序列化]:

I would say there are five fundamental kinds of [de]serialization that protobuf-net supports on a type-by-type basis (not including primitive types):

  1. 常规序列化.在这种模式下,将写入标准协议缓冲区,协议缓冲区中的一个字段用于您用ProtoMember标记或ImplicitFields自动选择的每个字段或属性. ...

  1. Normal serialization. In this mode, a standard protocol buffer is written, with one field in the protocol buffer for each field or property that you have marked with ProtoMember, or that has been auto-selected by ImplicitFields. ...

集合序列化.如果protobuf-net将特定数据类型标识为集合,则使用此模式对其进行序列化.幸运的是,集合类型不需要任何ProtoContract或ProtoMember属性,这意味着您可以轻松地序列化诸如List和T []之类的类型...

Collection serialization. If protobuf-net identifies a particular data type as a collection, it is serialized using this mode. Thankfully, collection types do not need any ProtoContract or ProtoMember attributes, which means you can serialize types such as List and T[] easily...

<snip>

Protobuf-net使用重复"字段(在协议缓冲区术语中)对集合进行序列化.因此,您应该能够安全地在版本之间更改集合类型.例如,您可以序列化Foo [],然后将其反序列化为List.

Protobuf-net serializes a collection using a "repeated" field (in protocol buffer lingo). Therefore, you should be able to safely change collection types between versions. For example, you can serialize a Foo[] and later deserialize it into a List.

因此,合同类型"的序列化与本文中的正常序列化"相对应-并且集合是 not 合同类型.这说明了Dynamic type is not a contract-type: TestType[]异常消息.

So serialization of a "contract type" corresponds to "normal serialization" in this article -- and collections are not contract types. This explains the Dynamic type is not a contract-type: TestType[] exception message.

作为一种解决方法,您可以将ProtoDynamicProperty打包在一个通用代理类型中,该类型可以保证与合同类型相对应并封装必要的类型信息,例如:

As a workaround, you can package your ProtoDynamicProperty inside a generic surrogate type that is guaranteed to correspond to a contract type and encapsulates the requisite type information, like so:

[ProtoContract]
public abstract class TypedObjectSurrogate
{
    protected TypedObjectSurrogate() { }

    [ProtoIgnore]
    public abstract object ObjectValue { get; }

    public static object CreateSurrogate<T>(T value)
    {
        if (value == null)
            return new TypedObjectSurrogate<T>();
        var type = value.GetType();
        if (type == typeof(T))
            return new TypedObjectSurrogate<T>(value);
        // Return actual type of subclass
        return Activator.CreateInstance(typeof(TypedObjectSurrogate<>).MakeGenericType(type), value);
    }
}

[ProtoContract]
public sealed class TypedObjectSurrogate<T> : TypedObjectSurrogate
{
    public TypedObjectSurrogate() : base() { }

    public TypedObjectSurrogate(T value)
        : base()
    {
        this.Value = value;
    }

    [ProtoIgnore]
    public override object ObjectValue
    {
        get { return Value; }
    }

    [ProtoMember(1)]
    public T Value { get; set; }
}

[ProtoBuf.ProtoContract]
class DataTransferType
{
    [ProtoBuf.ProtoIgnore]
    public object ProtoDynamicProperty { get; set; }

    [ProtoBuf.ProtoMember(1, DynamicType = true)]
    object ProtoDynamicPropertySurrogate
    {
        get
        {
            if (ProtoDynamicProperty == null)
                return null;
            return TypedObjectSurrogate.CreateSurrogate(ProtoDynamicProperty);
        }
        set
        {
            if (value is TypedObjectSurrogate)
                ProtoDynamicProperty = ((TypedObjectSurrogate)value).ObjectValue;
            else
                ProtoDynamicProperty = value;
        }
    }
}

[ProtoBuf.ProtoContract]
struct TestType
{
    [ProtoBuf.ProtoMember(1)]
    public string UselessProperty { get; set; }
}

这篇关于Protobuf-net动态类型数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆