2

自動シリアル化に関するShawnHarvgreaveのブログエントリとコンテンツパイプラインの概要に関するMSDNの記事を読みましたが、サポートされているタイプのリストが見つかりませんでした。

MSDNの引用:

XNA Game Studio 3.1以降、カスタムデータの.XNB形式へのシリアル化は、既存のコンテンツタイプライターがない単純なタイプに対して自動的に実行されます。

自動シリアル化でサポートされていないと推測しているQueueを使用しようとするまで、これに問題はありませんでした。System.Collections.Generic

それで、これによってサポートされるタイプのリストはありますか?そして、それがサポートされていない場合、私は自分ContentTypeWriterで書く必要がありContentTypeReaderますか?

4

1 に答える 1

5

互換性のあるタイプの完全なリストを提供するのは難しいです-シリアライザーは、これまでに見たことのないカスタムタイプと互換性を持たせようとするためです。したがって、互換性のあるクラスのリストを網羅することはできません。Shawnのブログ投稿にあるように:

デフォルトでは、タイプのすべてのパブリックフィールドとプロパティがシリアル化されます(読み取り専用ではない場合)。

しかし、コレクションクラスについて話しましょう。上記のルールにより、オブジェクトのコレクションはパブリックプロパティではないため(また、インデクサーはサポートされていないため) 、コレクションクラスは正しくシリアル化されません(リフレクションを使用する場合)。

このようなコレクションの自動シリアル化が組み込み機能ではない理由を指摘するのは興味深いことです。コレクションは通常IEnumerable<T>(実行するようQueue<T>に)実装し、シリアル化することができます。しかし、それは読み取り専用です。コレクションIEnumerableへの書き込みのような標準的なインターフェースはありません。したがって、それらを自動的に逆シリアル化する方法はありません。

幸い、XNAは、次のジェネリックコレクションタイプ用のカスタムリーダー/ライターを提供します

  • 配列
  • List<T>
  • Dictionary<TKey, TValue>

シリアライザーは、カスタムリーダー/ライターが利用可能な場合、それらを自動的に使用します。したがって、コレクションクラス(のようなQueue<T>)を処理する場合は、独自のクラスを作成する必要がありContentTypeWriterますContentTypeReader。幸い、これはそれほど難しいことではありません。テストされていない実装については、以下を参照してください

組み込み型の完全なリストについては、XNB形式の仕様を参照してください。繰り返しますが、これは組み込みタイプのみを対象としています。他のタイプは、リフレクションを通じて、またはカスタムのリーダー/ライターのペアを提供することによってサポートできます。


class QueueReader<T> : ContentTypeReader<Queue<T>>
{
    public override bool CanDeserializeIntoExistingObject { get { return true; } }

    protected override Queue<T> Read(ContentReader input, Queue<T> existingInstance)
    {
        int count = input.ReadInt32();
        Queue<T> queue = existingInstance ?? new Queue<T>(count);
        for(int i = 0; i < count; i++)
            queue.Enqueue(input.ReadObject<T>());
        return queue;
    }
}

[ContentTypeWriter]
class QueueWriter<T> : ContentTypeWriter<Queue<T>>
{
    public override string GetRuntimeReader(TargetPlatform targetPlatform)
    {
        return typeof(QueueReader<T>).AssemblyQualifiedName;
    }

    public override bool CanDeserializeIntoExistingObject { get { return true; } }

    protected override void Write(ContentWriter output, Queue<T> value)
    {
        output.Write(value.Count);
        foreach(var item in value)
            output.WriteObject<T>(item);
    }
}

ここでの私の実装は、WindowsGetRuntimeReaderではない場合を処理しないことに注意してください。targetPlatformまた、依存関係の問題が発生しないように、これらを適切なアセンブリに配置する必要があります。

于 2012-10-19T08:20:25.167 に答える