如何将C#反序列化与分层类结构结合使用

如何将C#反序列化与分层类结构结合使用,c#,class,serialization,hierarchy,C#,Class,Serialization,Hierarchy,我正在尝试将一些xml文件反序列化为一些类,这些类已简化为以下内容: [XmlRoot("person")] [Serializable] public class Person { [XmlElement] public Toy Toy { get; set; } } [Serializable] public class ActionMan : Toy { [XmlElement("guns")] public string Guns; } [Serial

我正在尝试将一些xml文件反序列化为一些类,这些类已简化为以下内容:

[XmlRoot("person")]
[Serializable]
public class Person
{
    [XmlElement]
    public Toy Toy { get; set; }
}

[Serializable]
public class ActionMan : Toy
{
    [XmlElement("guns")]
    public string Guns;
}

[Serializable]

public class Doll : Toy
{
    [XmlElement("name")]
    public  String Name;
}

[XmlInclude(typeof(Doll))]
[XmlInclude(typeof(ActionMan))]
public class Toy
{
}

[TestFixture]
public class ToyTest
{
    [Test]
    public void testHierarchy()
    {
        String filePath = @"test\brother.xml";
        String sisfilePath = @"test\sister.xml";
        var serializer = new XmlSerializer(typeof(Person));
        Person brother = (Person)serializer.Deserialize(new FileStream(filePath, FileMode.Open));
        Person sister = (Person)serializer.Deserialize(new FileStream(sisfilePath, FileMode.Open));

        Assert.IsNotNull(brother);
        Assert.IsNotNull(sister);
        Assert.IsAssignableFrom(typeof(ActionMan),brother.Toy);
        Assert.IsAssignableFrom(typeof(Doll),sister.Toy);
    }
}
我想使用c#序列化(我知道我可以使用我自己的反序列化程序),我想我可能只是缺少了一个我不知道的特定标记(我肯定我有多余的标记)

以下是一个xml文件:

<person>
  <doll>
    <name>Jill</name>
  </doll>
</person>

吉尔

我在第三个断言中得到的错误是“Expected:assignable from”,person应该包含一个“doll”属性而不是“Toy”属性,我指的是名称。XML节点必须与属性名称具有相同的名称-大小写很重要

当我尝试序列化您的结构(将ActionMan作为玩具的人)时,我得到了


我想这就是处理类型继承的方法。 但是我想您无法更改已经序列化的XML。

请尝试以下方法

public class Person 
{

    public Toy toy
    {
        get
        {
            return (doll == null) ? (Toy)actionMan : (Toy)doll;
        }

    }


    public Doll doll;
    public ActionMan actionMan;
}


public class Toy 
{

}


public class Doll : Toy
{
    public String name;

}


public class ActionMan : Toy
{
    public String guns;
}

class Program
{
    static void Main(string[] args)
    {

        Person brother = new Person();
        ActionMan am = new ActionMan();
        am.guns = "Laser Beam";
        brother.actionMan = am;

        Person sister = new Person();
        Doll d = new Doll();
        d.name = "Jill";
        sister.doll = d;

        Serialize(brother, "brother.xml");
        Serialize(sister, "sister.xml");

        Person b = Deserialize("brother.xml");
        Person s = Deserialize("sister.xml");

        Console.WriteLine(((ActionMan)b.toy).guns);
        Console.WriteLine(((Doll)s.toy).name);
        Console.Read();
    }

    public static Person Deserialize(String filename)
    {
        var serializer = new XmlSerializer(typeof(Person));
        return (Person)serializer.Deserialize(new FileStream(filename, FileMode.Open));

    }

    public static void Serialize(Person p, String filename){
        Stream stream = File.Open(filename, FileMode.Create);
        XmlSerializer s = new XmlSerializer(typeof(Person));
        s.Serialize(stream, p);
        stream.Close();

    }
你可以从这里扩展。请记住,在属性名称中,大小写很重要。我得到的序列化输出是

brother.xml

<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <actionMan>
    <guns>Laser Beam</guns>
  </actionMan>
</Person>

我所做的是按照我想要的方式设计类结构,填充一些基本数据,然后序列化它。然后检查它是如何序列化和调整Xml属性的。如果你的
Toy
类只有几个派生,那么你可以用一个action-man字段和一个doll字段分别反序列化它们,这两个字段可能是空的,也可能不是空的

或者从Xml文件转到c类,我使用
xsd.exe
工具生成一个
.xsd
文件,其中包含
xsd mydata.Xml
,然后从该文件生成一个c类文件,其中包含
xsd/c/l:cs mydata.xsd
。然后我检查类数据,以获得关于如何定义类以及使用哪些属性的线索


链接到Microsoft提供的工具。

为您的架构创建xsd,然后使用xsd生成序列化程序代码。如果您修改类的源代码,则可以修改XML以外的任何内容。如果可能的话,我想使用轻量级的、标准的、最重要的是非生成代码。如果我一定要使用生成的序列化程序,那么很好,但我认为可能有一种更简单的方法我没有。你能检查一下使用Debugger加载的数据吗?很好地解释了其他人的答案。@tou-a)首先我+1另一个答案,b)我根据我的经验报告,即使它与其他人的经验相同,c)我还使用
xsd
添加了一个新想法。这里的问题到底是什么?Doll和ActionMan类都继承自Toy类。这就是为什么将其中一个实例亲自指定给toy属性是可行的。诀窍在于toy属性的get方法,以及类Person包含每种类型的变量Doll和ActionMan。
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <actionMan>
    <guns>Laser Beam</guns>
  </actionMan>
</Person>
<?xml version="1.0"?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <doll>
    <name>Jill</name>
  </doll>
</Person>
Laser Beam
Jill