C# XNA&x27支持哪些类型;s自动XNB序列化?
我读过Shawn Harvgreave关于自动序列化的博客文章和MSDN关于内容管道概述的文章,但是我找不到支持的类型列表 引用MSDN: 从XNA Game Studio 3.1开始,自定义数据的序列化 .XNB格式会自动为不需要的简单类型执行 拥有现有的内容类型编写器 在尝试使用C# XNA&x27支持哪些类型;s自动XNB序列化?,c#,serialization,xna,content-pipeline,C#,Serialization,Xna,Content Pipeline,我读过Shawn Harvgreave关于自动序列化的博客文章和MSDN关于内容管道概述的文章,但是我找不到支持的类型列表 引用MSDN: 从XNA Game Studio 3.1开始,自定义数据的序列化 .XNB格式会自动为不需要的简单类型执行 拥有现有的内容类型编写器 在尝试使用System.Collections.Generic中的队列之前,我一直没有遇到过这个问题,我猜自动序列化不支持该队列 那么,有没有一个列表支持这种类型?如果不支持,我是否需要编写自己的ContentTypeWrit
System.Collections.Generic
中的队列之前,我一直没有遇到过这个问题,我猜自动序列化不支持该队列
那么,有没有一个列表支持这种类型?如果不支持,我是否需要编写自己的ContentTypeWriter
和ContentTypeReader
?提供兼容类型的完整列表是一件棘手的事情,因为序列化程序试图与以前从未见过的自定义类型兼容。因此,任何兼容类的列表都不可能详尽无遗。正如上面所说:
默认情况下,它将序列化类型的所有公共字段和属性(假定它们不是只读的)
但让我们谈谈收集类。根据上述规则,集合类不会被正确序列化(在使用反射时),因为它们的对象集合不是公共属性(而且不支持索引器)
有趣的是,要指出为什么像这样自动序列化集合不是内置功能。集合通常实现IEnumerable
(与Queue
类似),可以序列化。但这是只读的。没有像IEnumerable
这样的标准接口来编写集合。所以没有办法自动反序列化它们
幸运的是,XNA为以下通用集合类型提供了自定义读写器:
- 阵列
列表
字典
序列化程序会在自定义读写器可用时自动使用它们。因此,如果希望它处理集合类(如队列
),则必须为其创建自己的ContentTypeWriter
和ContentTypeReader
。幸运的是,这并不难——请参阅下面未经测试的实现
有关内置类型的完整列表,请参阅规范。同样,这只包括内置类型。其他类型可以通过反射或提供自定义读写器对来支持
class QueueReader:ContentTypeReader
{
public override bool CanDeserializeIntoExistingObject{get{return true;}}
受保护的覆盖队列读取(ContentReader输入,队列存在实例)
{
int count=input.ReadInt32();
队列队列=现有实例??新队列(计数);
for(int i=0;i
请注意,我在这里实现的GetRuntimeReader
不能处理targetPlatform
不是Windows的情况。您需要将这些文件放入正确的程序集中,以避免出现依赖性问题。谢谢Andrew。你证实了我的怀疑。
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);
}
}