2012-10-18 46 views
2

我读过关于自动序列化的Shawn Harvgreave的博客文章和有关内容管道概述的MSDN文章,但是我找不到支持的类型列表。XNA的自动XNB序列化支持哪些类型?

引述MSDN:

与XNA游戏工作室3.1开始,自定义数据的 序列化的.XNB格式自动为简单类型不 做有一个现有的内容类型的作家。

,直到我试图从System.Collections.Generic我猜不是由自动序列化支持使用Queue我还没有与此问题。

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

回答

5

提供兼容类型的完整列表非常棘手 - 因为序列化程序试图与自定义类型兼容,这是以前从未见过的类型。所以任何兼容类的列表都不能详尽无遗。由于Shawn's blog post说:

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

但让我们来谈谈集合类。通过上述规则,集合类将不会被正确序列化(当使用反射时),因为它们的对象集合不是公共属性(并且索引器不受支持)。

有趣的是指出为什么自动序列化这样的集合不是一个内置的功能。一个集合通常实现IEnumerable<T>(如Queue<T>),它可以被序列化。但这是只读的。没有标准接口,如IEnumerable写入集合。所以没有办法自动将它们反序列化!

幸运的是,XNA提供定制的读/写器以下泛型集合类型

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

串行器会自动使用自定义的读/写器当它们可用时。所以如果你想要它处理一个集合类(如Queue<T>),那么你必须为它创建自己的ContentTypeWriterContentTypeReader。幸运的是,这并不难 - 请参阅下面的未经测试的实施。

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


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。你需要把它们放在正确的程序集中,这样你就不会遇到依赖性问题。

+0

谢谢安德鲁。你证实了我的怀疑。 –

相关问题