XNA的自动XNB序列化支持哪些类型?

我已经阅读了Shawn Harvgreave关于自动序列化的博客文章和关于内容管道概述的MSDN文章,但我找不到支持的类型列表。

引用MSDN:

从XNA Game Studio 3.1开始,对于没有现有内容类型编写器的简单类型,自动完成自定义数据到.XNB格式的序列化。

我没有遇到过这个问题,直到我尝试使用System.Collections.Generic中的Queue ,我猜测它不受自动序列化的支持。

那么,是否有一个支持的类型列表? 如果不支持,我是否需要编写自己的ContentTypeWriterContentTypeReader

提供完整的兼容类型列表很棘手 – 因为序列化程序试图与之前从未见过的自定义类型兼容。 因此,任何兼容类列表都不能详尽无遗。 正如Shawn的博客文章所说:

默认情况下,它将序列化您的类型的所有公共字段和属性(假设它们不是只读的)。

但是我们来谈谈集合类。 根据上述规则,集合类将无法正确序列化( 使用reflection时 ),因为它们的对象集合不是公共属性(也不支持索引器)。

有趣的是指出为什么自动序列化这样的集合不是内置function。 集合通常实现IEnumerable (如Queue ),可以序列化。 但这是只读的。 没有像IEnumerable这样的标准界面来写入集合。 所以没有办法自动反序列化它们!

幸运的是, XNA为以下通用集合类型提供自定义读取器/写入器

  • 数组
  • List
  • Dictionary

序列化程序在可用时自动使用自定义读取器/写入器。 因此,如果您希望它处理集合类(如Queue ),那么您必须为它创建自己的ContentTypeWriterContentTypeReader 。 幸运的是,这并不太难 – 请参阅下面的未经测试的实现。

有关内置类型的完整列表,请参阅XNB格式规范 。 这只是涵盖了内置类型。 可以通过reflection或通过提供自定义读取器/写入器对来支持其他类型。


 class QueueReader : ContentTypeReader> { public override bool CanDeserializeIntoExistingObject { get { return true; } } protected override Queue Read(ContentReader input, Queue existingInstance) { int count = input.ReadInt32(); Queue queue = existingInstance ?? new Queue(count); for(int i = 0; i < count; i++) queue.Enqueue(input.ReadObject()); return queue; } } [ContentTypeWriter] class QueueWriter : ContentTypeWriter> { public override string GetRuntimeReader(TargetPlatform targetPlatform) { return typeof(QueueReader).AssemblyQualifiedName; } public override bool CanDeserializeIntoExistingObject { get { return true; } } protected override void Write(ContentWriter output, Queue value) { output.Write(value.Count); foreach(var item in value) output.WriteObject(item); } } 

请注意,我在这里实现的GetRuntimeReader不能处理targetPlatform不是Windows的情况。 而且你需要将它们放在正确的程序集中,这样就不会出现依赖性问题。