互換性のあるタイプの完全なリストを提供するのは難しいです-シリアライザーは、これまでに見たことのないカスタムタイプと互換性を持たせようとするためです。したがって、互換性のあるクラスのリストを網羅することはできません。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
また、依存関係の問題が発生しないように、これらを適切なアセンブリに配置する必要があります。