提供兼容类型的完整列表很棘手 - 因为序列化程序尝试与以前从未见过的自定义类型兼容。因此任何兼容类的列表都不可能是详尽的。作为肖恩的博客文章 http://blogs.msdn.com/b/shawnhar/archive/2009/03/25/automatic-xnb-serialization-in-xna-game-studio-3-1.aspx says:
默认情况下,它将序列化您类型的所有公共字段和属性(假设它们不是只读的)。
但我们来谈谈集合类。根据上述规则,集合类将无法正确序列化(当使用反射时),因为它们的对象集合不是公共财产(而且,不支持索引器)。
有趣的是指出why像这样自动序列化集合并不是内置功能。集合通常实现IEnumerable<T>
(like Queue<T>
),可以序列化。但那是只读的。没有像这样的标准接口IEnumerable
for writing到收藏。所以没有办法自动反序列化它们!
幸运的是,XNA 为以下通用集合类型提供自定义读取器/编写器:
- Arrays
List<T>
Dictionary<TKey, TValue>
当自定义读取器/写入器可用时,序列化器会自动使用它们。因此,如果您希望它处理集合类(例如Queue<T>
),那么你必须创建自己的ContentTypeWriter
and ContentTypeReader
为了它。幸运的是,这并不太难 - 请参阅下文untested执行。
有关内置类型的完整列表,请参阅XNB 格式 http://xbox.create.msdn.com/en-US/sample/xnb_format规格。同样,这仅涵盖了built-in类型。其他类型可以通过反射或提供自定义读取器/写入器对来支持。
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);
}
}
请注意,我的实现GetRuntimeReader
这里不处理以下情况targetPlatform
不是Windows。您需要将它们放入正确的程序集中,这样就不会出现依赖性问题。