提供兼容类型的完整列表非常棘手 - 因为序列化程序试图与自定义类型兼容,这是以前从未见过的类型。所以任何兼容类的列表都不能详尽无遗。由于Shawn's blog post说:
默认情况下,它会序列化您的类型的所有公共字段和属性(假设它们不是只读的)。
但让我们来谈谈集合类。通过上述规则,集合类将不会被正确序列化(当使用反射时),因为它们的对象集合不是公共属性(并且索引器不受支持)。
有趣的是指出为什么自动序列化这样的集合不是一个内置的功能。一个集合通常实现IEnumerable<T>
(如Queue<T>
),它可以被序列化。但这是只读的。没有标准接口,如IEnumerable
,将写入集合。所以没有办法自动将它们反序列化!
幸运的是,XNA提供定制的读/写器以下泛型集合类型:
- 阵列
List<T>
Dictionary<TKey, TValue>
串行器会自动使用自定义的读/写器当它们可用时。所以如果你想要它处理一个集合类(如Queue<T>
),那么你必须为它创建自己的ContentTypeWriter
和ContentTypeReader
。幸运的是,这并不难 - 请参阅下面的未经测试的实施。
有关内置类型的完整列表,请参阅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。你需要把它们放在正确的程序集中,这样你就不会遇到依赖性问题。
谢谢安德鲁。你证实了我的怀疑。 –