繁体   English   中英

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

[英]How to serialize a class that contains objects of other classes (recursive serializing?)

我怎样才能做到这一点? 或者序列化程序会自动进行递归,并将所有这些子对象序列化为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();
}

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

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

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

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

添加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>();
}

用法:

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(Map));
serializer.Serialize(mapWriter, savedMap);

只要图中的所有对象都是可序列化的,它将序列化整个对象图(对象及其通过公共成员以递归方式公开的任何对象)。 不同的序列化程序对可序列化的内容有不同的规则。 例如,XmlSerializer需要一个默认的公共构造函数。

此外,XML序列化程序需要能够根据这些类型的类型信息和属性来确定它将序列化的类型。 例如,假设您有一个具有Animal类型属性的类,但在运行时XmlSerializer在那里找到一个类型为Dog的对象。 为了支持这一点,您需要使用XmlInclude属性让它提前知道它需要支持Dog。

为了将对象图的一部分保留在序列化输出之外,您将使用XmlIgnore属性。 不同的序列化程序也有不同的属性包括/忽略等。

希望这有助于澄清一点。 您可能还想在MSDN中阅读此主题

你需要多少控制权? 你总是可以实现IXmlSerializable -

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx

关于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);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM