如何序列化包含其他类对象的类(递归序列化?)

Joh*_*nny 15 .net c# xml serialization xml-serialization

我怎样才能做到这一点?或者序列化程序会自动进行递归,并将所有这些子对象序列化为XML吗?

举个例子,如何序列化包含其他类对象的类本身!那是这个问题的核心!

我试过这个,并没有向目标XML文件输出任何内容(XML头除外).

我的问题是我需要序列化一个简单的类,它只包含一个List对象.但是,这些实体也是Lod List对象.(另一个好处是,如果我可以避免某些组件的序列化,因为一些组件是派生的并且在其中包含字典).

public void SaveCurrent(string MapFileName)
{
    string MapPath = world_.game_.Content.RootDirectory + "/Maps/" + MapFileName + ".xml";
    StreamWriter MapWriter = new StreamWriter(MapPath);

    Map SavedMap = new Map();
    SavedMap.Entities = world_.Entities;
    XmlSerializer xSerializer = new XmlSerializer(SavedMap.GetType());

    xSerializer.Serialize(MapWriter, SavedMap);
    MapWriter.Close();
}
Run Code Online (Sandbox Code Playgroud)

这是进行序列化的代码片段.

public class Map
{
    internal string MapName;
    internal string MapDescription;
    internal string MapAuthor;
    public List<Entity> Entities = new List<Entity>();
}
Run Code Online (Sandbox Code Playgroud)

这是序列化的类.如果从同一个程序集调用序列化,内部会被视为公共吗?代码在SavedMap.GetType()函数处抛出异常,我也尝试typeof(Map)过,但没有成功.我想这是因为我需要一些其他方法来处理每个新类(深度序列化)我该怎么做?

另外,我在一些例子中发现,没有接口继承或属性,因此我也没有添加它们,但我打算使用IXmlSerializable,虽然我不知道如何在WriteXML中调用另一个序列化实现.

pr0*_*g3r 6

添加Serializable和XmlInclude您的类:

[System.Serializable]
[System.Xml.Serialization.XmlInclude(typeof(Entity))]
public class Map
{
    internal string MapName;
    internal string MapDescription;
    internal string MapAuthor;
    public List<Entity> Entities = new List<Entity>();
}
Run Code Online (Sandbox Code Playgroud)

用法:

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Map));
serializer.Serialize(mapWriter, savedMap);
Run Code Online (Sandbox Code Playgroud)


Syl*_*quy 2

关于 Josh Einstein 提到的类型问题,您不必使用 XmlInclude 属性:您还可以将类型列表传递给序列化器(签名为XmlSerializer(Type baseType, Type[] extraTypes))。尤其是当额外类型列表有可能随着时间的推移而增长时,应该这样做。

查找额外类型可以通过对要序列化的对象的反射来完成,也可以通过在启动时对加载的程序集进行反射来获取任何所需的类型来完成。

编辑:原始示例:

public abstract class Animal
{
}

public class Dog : Animal
{
}

public class Cat : Animal
{
}

public static class AnimalSerializer
{
    public static void Serialize(List<Animal> animals, Stream stream)
    {
        List<Type> animalTypes = new List<Type>();
        foreach (Animal animal in animals)
        {
            Type type = animal.GetType();
            if (!animalTypes.Contains(type))
            {
                animalTypes.Add(type);
            }
        }
        XmlSerializer serializer = new XmlSerializer(typeof(List<Animal>), animalTypes.ToArray());
        serializer.Serialize(stream, animals);
    }
}
Run Code Online (Sandbox Code Playgroud)