Protobuf-Net错误消息:没有为类型定义Serializer:System.Type

时间:2012-09-18 10:50:40

标签: c# protocol-buffers protobuf-net system.type

尝试序列化List<Tuple<string, Type, object>>时收到以下错误消息:没有为类型定义Serializer:System.Type

我尝试了两种方法,只是序列化上面的集合或序列化一个具有与protoMember相同的集合的类。两者都会导致相同的错误消息。

这是不受支持的类型吗?我认为它是受支持的,我忽略了别的东西,但也许我不正确?

感谢任何可能有助于解决此问题的指示......

1 个答案:

答案 0 :(得分:12)

编辑:

r580

中包含对Type序列化的支持

protobuf-net旨在序列化您的数据,而非您的实施; Type是一个实现细节。严格来说,添加起来并不是非常困难(某些特定于实现的细节已经基本上通过程序集限定名称存储了Type信息),但是:它不是一个关键场景,并且在许多方面我鼓励你序列化 - 协议缓冲的全部意义在于你可以在任何平台上加载数据,版本容差是一个关键特性。存储Type信息会违反这两种信息。

还应该注意的是,大多数其他序列化程序(可能BinaryFormatter除外,它已经破坏了平台/版本容忍的每个规则) 拒绝序列化Type; XmlSerializerDataContractSerializerJavaScriptSerializer 所有 为此方案抛出异常(我刚检查过它们)。

此外:object 甚至更少可支持,除非您使用DynamicType功能。


以下是如何通过Type上的代理人来完成的:

using ProtoBuf;
using ProtoBuf.Meta;
using System;
using System.Runtime.Serialization;

static class Program
{
    public static void Main(string[] args)
    {
        // register a surrogate for Type
        RuntimeTypeModel.Default.Add(typeof(Type), false)
                                .SetSurrogate(typeof(TypeSurrogate));
        // test it
        var clone = Serializer.DeepClone(new Foo { Type = typeof(string) });
    }
}

[ProtoContract]
class TypeSurrogate
{
    [ProtoMember(1)]
    public string AssemblyQualifiedName { get; set; }
    // protobuf-net wants an implicit or explicit operator between the types
    public static implicit operator Type(TypeSurrogate value)
    {
        return value==null ? null : Type.GetType(value.AssemblyQualifiedName);
    }
    public static implicit operator TypeSurrogate(Type value)
    {
        return value == null ? null : new TypeSurrogate {
            AssemblyQualifiedName  = value.AssemblyQualifiedName };
    }
}

[DataContract]
public class Foo
{
    [DataMember(Order=1)]
    public Type Type { get; set; }
}