Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.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#_Xml_Generics_Xml Serialization - Fatal编程技术网

C# 如何使用泛型属性序列化/反序列化类?

C# 如何使用泛型属性序列化/反序列化类?,c#,xml,generics,xml-serialization,C#,Xml,Generics,Xml Serialization,我无法反序列化包含泛型属性T的类。我得到的异常是: 无法生成临时类(结果=1)。错误CS0030:无法执行 将类型“教师”转换为“程序员”错误 CS0029:无法将类型“Programmer”隐式转换为 “老师” 我的班级结构有一个人为的例子: [Serializable] public class Person<T> where T : Profession { [XmlElement("Teacher", typeof(Teacher))] [XmlElement

我无法反序列化包含泛型属性T的类。我得到的异常是:

无法生成临时类(结果=1)。错误CS0030:无法执行 将类型“教师”转换为“程序员”错误 CS0029:无法将类型“Programmer”隐式转换为 “老师”

我的班级结构有一个人为的例子:

[Serializable]
public class Person<T> where T : Profession
{
    [XmlElement("Teacher", typeof(Teacher))]
    [XmlElement("Programmer", typeof(Programmer))]
    public T Profession { get; set; }
}

[Serializable]
[XmlInclude(typeof(Teacher))] // A Subclass
[XmlInclude(typeof(Programmer))] // A Subclass
public class Profession
{}

[Serializable]
public class Teacher : Profession
{
    [XmlElement]
    public int Salary { get; set; }
}


[Serializable]
public class Programmer : Profession
{
    [XmlElement]
    public long MassiveSalary { get; set; }
}
[可序列化]
公共类人员,其中T:职业
{
[XmlElement(“教师”,类型(教师))]
[XmlElement(“程序员”,类型(程序员))]
公共T职业{get;set;}
}
[可序列化]
[xmlclude(typeof(Teacher))]//一个子类
[xmlclude(typeof(程序员))]//一个子类
公共职业
{}
[可序列化]
公营班主任:专业
{
[XmlElement]
公共整数{get;set;}
}
[可序列化]
公共类程序员:专业
{
[XmlElement]
公共长体量数组{get;set;}
}
我要反序列化的XML文件的结构是:

<Person>
    <Programmer/>
</Person>

或者可能是

<Person>
    <Teacher />
</Person>

基本上描述了相同的问题,但使用的解决方案/解决方法对我来说没有意义。在这种情况下,解决方法是定义不同类型(本例中为教师/程序员)之间的隐式转换

最后一点是,如果我注释掉其中任何一个专业,那么我可以反序列化至少一个版本的文件。例如:

[Serializable]
public class Person<T> where T : Profession
{
    // Comment out 'Programmer' and I can deserialise all files with a 'Teacher' XMLElement
    [XmlElement("Teacher", typeof(Teacher))]
    //[XmlElement("Programmer", typeof(Programmer))]

    public T Profession { get; set; }
}
[可序列化]
公共类人员,其中T:职业
{
//注释掉“程序员”,我就可以用“教师”XMLElement反序列化所有文件
[XmlElement(“教师”,类型(教师))]
//[XmlElement(“程序员”,类型(程序员))]
公共T职业{get;set;}
}

然后可以反序列化该文件。有人能解释一下是否有可能做到这一点,或者建议进行合理的锻炼吗?谢谢

尝试以下xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq; 

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<Root>" +
                   "<Person>" +
                      "<Programmer/>" +
                      "<Teacher/>" +
                   "</Person>" +
                "</Root>";

            XElement root = XElement.Parse(xml);

            string[] persons = root.Descendants("Person").Elements().Select(x => x.Name.LocalName).ToArray();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串xml=
"" +
"" +
"" +
"" +
"" +
"";
XElement root=XElement.Parse(xml);
string[]persons=root.subscriptions(“Person”).Elements().Select(x=>x.Name.LocalName.ToArray();
}
}
}

尝试以下xml linq:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq; 

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<Root>" +
                   "<Person>" +
                      "<Programmer/>" +
                      "<Teacher/>" +
                   "</Person>" +
                "</Root>";

            XElement root = XElement.Parse(xml);

            string[] persons = root.Descendants("Person").Elements().Select(x => x.Name.LocalName).ToArray();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用System.Xml;
使用System.Xml.Linq;
命名空间控制台应用程序1
{
班级计划
{
静态void Main(字符串[]参数)
{
字符串xml=
"" +
"" +
"" +
"" +
"" +
"";
XElement root=XElement.Parse(xml);
string[]persons=root.subscriptions(“Person”).Elements().Select(x=>x.Name.LocalName.ToArray();
}
}
}

您可以更改XML格式吗?或者它是固定的?哦,你事先知道你是反序列化一个
还是
,或者你需要在反序列化过程中确定吗?我可以稍微改变一下格式-你有什么建议?我会提前知道要反序列化的类型。如果您提前知道,为什么要更改元素名称?对于所有泛型类型,将其保留为
。每个专业的根元素名称都是不可修改的。因此XML文档必须包含“”或“”标记,而不是标记。我曾考虑放弃通用属性,而是在我的“个人”类中拥有一个“职业”。然后我可以反序列化任何职业,并将其转换为更具体的类型。例如:[xmlement(“教师”,typeof(教师))][xmlement(“程序员”,typeof(程序员))]公共职业职业{get;set;}。这可以正常工作,但最好使用通用的T。您能更改XML格式吗?或者它是固定的?哦,你事先知道你是反序列化一个
还是
,或者你需要在反序列化过程中确定吗?我可以稍微改变一下格式-你有什么建议?我会提前知道要反序列化的类型。如果您提前知道,为什么要更改元素名称?对于所有泛型类型,将其保留为
。每个专业的根元素名称都是不可修改的。因此XML文档必须包含“”或“”标记,而不是标记。我曾考虑放弃通用属性,而是在我的“个人”类中拥有一个“职业”。然后我可以反序列化任何职业,并将其转换为更具体的类型。例如:[xmlement(“教师”,typeof(教师))][xmlement(“程序员”,typeof(程序员))]公共职业职业{get;set;}。这将正常工作,但最好使用通用的T。