gpt4 book ai didi

object - Protobuf-net 动态类型数组

转载 作者:行者123 更新时间:2023-12-04 20:10:41 29 4
gpt4 key购买 nike

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

错误:

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 构建

最佳答案

您的困难由 DynamicType 的限制解释(尽管不完全)提到 hereformer project site对于 protobuf-net:

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.



那么, 究竟是什么意思?契约(Contract)类型?如前所述,原始类型不是契约类型,但仅此而已吗?来自 Protobuf-net: the unofficial manual: Forms of type serialization in 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. 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. ...

  2. 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 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.



因此,“契约(Contract)类型”的序列化对应于本文中的“正常序列化”——并且集合不是契约(Contract)类型。这解释了 Dynamic type is not a contract-type: TestType[]异常消息。

作为解决方法,您可以打包您的 ProtoDynamicProperty在保证对应于契约(Contract)类型并封装必要类型信息的通用代理类型中,如下所示:
[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; }
}

关于object - Protobuf-net 动态类型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17656133/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com