Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何序列化包含其他类对象的类(递归序列化?)_C#_.net_Xml_Serialization_Xml Serialization - Fatal编程技术网

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

C# 如何序列化包含其他类对象的类(递归序列化?),c#,.net,xml,serialization,xml-serialization,C#,.net,Xml,Serialization,Xml Serialization,我该怎么做?或者序列化程序会自动执行递归,并将所有这些子对象序列化为XML吗 给我一个例子,如何序列化包含其他类对象的类!这就是这个问题的核心 我试过了,但它没有向目标XML文件输出任何内容(XML头除外) 我的问题是我需要序列化一个简单的类,它只保存一个列表对象。但是,这些实体也可以列出对象。(另一个好处是,如果我可以避免某些组件的序列化,因为有些组件是派生的,并且其中包含字典) 这就是进行序列化的代码片段 public class Map { internal string MapN

我该怎么做?或者序列化程序会自动执行递归,并将所有这些子对象序列化为XML吗

给我一个例子,如何序列化包含其他类对象的类!这就是这个问题的核心

我试过了,但它没有向目标XML文件输出任何内容(XML头除外)

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

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

public class Map
{
    internal string MapName;
    internal string MapDescription;
    internal string MapAuthor;
    public List<Entity> Entities = new List<Entity>();
}
公共类映射
{
内部字符串映射名;
内部字符串映射描述;
内部字符串映射器;
公共列表实体=新列表();
}

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


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

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

此外,XML序列化程序需要能够仅根据类型信息和这些类型的属性来判断它将序列化的类型。例如,假设您有一个属性为Animal类型的类,但在运行时XmlSerializer会在其中找到一个类型为Dog的对象。要支持这一点,您需要使用属性来允许它提前知道它需要养狗

为了防止对象图的某些部分出现在序列化输出之外,您可以使用该属性。不同的序列化程序也有不同的包含/忽略等属性


希望这有助于澄清一点。您可能还想了解一下。

您需要多少控制?您始终可以实现IXmlSerializable-


关于Josh Einstein提到的类型问题,您不必使用XmlInclude属性:您还可以将类型列表传递给序列化程序(签名为
XmlSerializer(类型baseType,类型[]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);
    }
}
公共抽象类动物
{
}
公营狗:动物
{
}
公猫:动物
{
}
公共静态类动物序列化器
{
公共静态void序列化(列出动物、流)
{
List animalTypes=新列表();
foreach(动物中的动物)
{
Type=animal.GetType();
如果(!animalTypes.Contains(type))
{
添加(类型);
}
}
XmlSerializer serializer=新的XmlSerializer(typeof(List),animalTypes.ToArray());
序列化器。序列化(流、动物);
}
}

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

您可以分享您尝试过的示例吗?很抱歉,我之前没有这么做。“如果从同一程序集调用序列化,内部是否可以算作公共成员?”否。XmlSerializer只考虑公共成员。(事实上,XmlSerializer创建了一个动态程序集来保存执行序列化和反序列化的代码,因此实际的序列化总是在与代码不同的程序集中进行。)感谢您的提示。我已经将列表更改为public,但现在我得到了“有一个错误反映类型”异常。现在错误是实体类本身?(重新编辑08:26Z)您说它抛出了什么;但最内部的异常是什么?我猜它无法识别类型,在这种情况下,请参见Josh已经提到的
[xmlclude]
。我可以添加[XmlIgnore]在类实现中?由于列表中的多态性,我不能忽略InputComponent对象!不,AttributeTargets只允许您在字段、属性、参数或ReturnValue上指定XmlIgnore,尽管我不确定它将如何用于最后两个。这是我注意到并想问的另一件事!您可以共享一个示例?正是我需要的!谢谢!回答得很好!
[System.Serializable][System.Xml.Serialization.xmlclude(typeof(Entity))]
XmlSerializer.p.s实际上并不需要它。另外,请记住“列表实体”应该是列表,而不是IList。
[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);