Protobuf-Net error message: No Serializer defined for type: System.Type

前端 未结 1 1115
小鲜肉
小鲜肉 2020-12-30 07:38

I am getting the following error message when trying to serialize List>: No Serializer defined for type: System.Type

相关标签:
1条回答
  • 2020-12-30 08:22

    Edit:

    Support for Type serialization is included in r580


    protobuf-net is intended to serialize your data, not your implementation; Type is an implementation detail. Strictly speaking, it wouldn't be hugely hard to add (some of the implementation-specific details already essentially end up storing Type info, via the assembly-qualified-name), but: it isn't a key scenario, and in many ways is not something I would encourage you to serialize - the whole point of protocol buffers is that you can load the data on any platform, with version tolerance a key feature. Storing Type information violates both of these.

    It should also be noted that most other serializers (except perhaps BinaryFormatter, which already breaks every rule of platform/version-tolerance) will also refuse to serialize a Type; XmlSerializer, DataContractSerializer, JavaScriptSerializer etc all throw an exception for this scenario (I just checked them).

    Additionally: object is even less supportable, unless you use the DynamicType feature.


    Here's how it could be done via a surrogate on 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; }
    }
    
    0 讨论(0)
提交回复
热议问题