12

シリアル化しようとすると、次のエラーメッセージが表示されList<Tuple<string, Type, object>>ます。タイプにシリアライザーが定義されていません:System.Type

上記のコレクションをシリアル化するか、protoMemberとして定義された同じコレクションを持つクラスをシリアル化するだけで、両方を試しました。どちらも同じエラーメッセージになります。

これはサポートされていないタイプですか?私はそれがサポートされていると思います、そして私は何か他のものを見落としました、しかし多分私は間違っていますか?

これを解決するのに役立つ可能性のあるポインタをありがとう...

4

1 に答える 1

15

編集:

シリアル化のサポートTypeはr580に含まれています


protobuf-netは、実装ではなく、データをシリアル化することを目的としています。Type実装の詳細です。厳密に言えば、追加するのはそれほど難しいことではありません(実装固有の詳細の一部はType、アセンブリ修飾名を介して、すでに基本的に情報を格納することになります)が、重要なシナリオではなく、多くの点でシリアル化することをお勧めするものではありません。プロトコルバッファの要点は、バージョントレランスが重要な機能であり、任意のプラットフォームにデータをロードできることです。情報の保存Typeは、これらの両方に違反します。

また、他のBinaryFormatterほとんどのシリアライザー(おそらく、プラットフォーム/バージョン許容度のすべてのルールをすでに破っているを除く)Type、 ;のシリアル化を拒否することに注意してください。XmlSerializer、、などはすべてDataContractSerializer、このシナリオの例外をスローします(私はそれらをチェックしました)。JavaScriptSerializer

さらに、この機能を使用しない限り、サポート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; }
}
于 2012-09-18T11:10:08.953 に答える