XNA 的自动 XNB 序列化支持哪些类型? [英] Which types are supported by XNA's Automatic XNB Serialization?

查看:48
本文介绍了XNA 的自动 XNB 序列化支持哪些类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've read Shawn Harvgreave's blog entry about automatic serialization and the MSDN article on an overview of the content pipeline, but I couldn't find a list of the types supported.

引用 MSDN:

从 XNA Game Studio 3.1 开始,自定义数据序列化为.XNB 格式是自动完成的简单类型,不拥有现有的内容类型编写器.

Starting with XNA Game Studio 3.1, the serialization of custom data to the .XNB format is done automatically for simple types that do not have an existing content type writer.

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

I haven't had problems with this until I tried to use a Queue from System.Collections.Generic which I'm guessing isn't supported by the automatic serialization.

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

So, is there a list of types supported by this? And if it isn't supported, will I need to write my own ContentTypeWriter and ContentTypeReader?

推荐答案

提供兼容类型的完整列表很棘手 - 因为序列化程序试图与它以前从未见过的自定义类型兼容.因此,任何兼容类的列表都不能详尽无遗.作为 Shawn 的博文 说:

Providing a complete list of compatible types is tricky - because the serializer tries to be compatible with custom types it has never seen before. So any list of compatible classes cannot be exhaustive. As Shawn's blog post says:

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

By default it will serialize all the public fields and properties of your type (assuming they are not read-only).

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

But let's talk about collection classes. By the above rule, collection classes won't be serialized correctly (when using reflection), because their collection of objects is not a public property (also, indexers aren't supported).

指出为什么自动序列化这样的集合不是内置功能很有趣.集合通常实现 IEnumerable(就像 Queue 那样),它可以被序列化.但那是只读的.没有像 IEnumerable 这样的标准接口来写入集合.所以没有办法自动反序列化它们!

It's interesting to point out why automatically serializing a collection like this isn't a built-in feature. A collection usually implements IEnumerable<T> (like Queue<T> does), which could be serialized. But that's read-only. There's no standard interface like IEnumerable for writing to collections. So there's no way to automatically deserialize them!

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

  • 数组
  • 列表
  • 字典

序列化程序会在自定义读取器/写入器可用时自动使用它们.所以如果你想让它处理一个集合类(比如 Queue),那么你必须为它创建你自己的 ContentTypeWriterContentTypeReader.幸运的是,这并不太难 - 请参阅下面的未经测试实现.

The serializer automatically uses custom readers/writers when they are available. So if you want it to handle a collection class (like Queue<T>), then you must create your own ContentTypeWriter and ContentTypeReader for it. Fortunately this isn't too hard - see below for an untested implementation.

有关内置类型的完整列表,请参阅 XNB格式规范.同样,这仅涵盖了内置类型.其他类型可以通过反射或提供自定义读写器对来支持.

For a full list of built-in types, see the XNB Format specification. Again this just covers the built-in types. Other types can be supported through reflection or by providing custom reader/writer pairs.

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 的情况.而且您需要将它们放在正确的程序集中,以免出现依赖性问题.

Note that my implementation of GetRuntimeReader here doesn't handle cases where targetPlatform isn't Windows. And you'll need to put these in the right assemblies so you don't get dependency issues.

这篇关于XNA 的自动 XNB 序列化支持哪些类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆