我能';用XmlSerializer序列化C#中的对象列表

我能';用XmlSerializer序列化C#中的对象列表,c#,xml-serialization,xmlserializer,C#,Xml Serialization,Xmlserializer,我有许多测试实现接口IDoTest的列表,我想将其存储在一个文件中。我还想从这个文件中读取 简单地使用XmlSerializer来存储我的IDoTest列表中的对象似乎很自然。但是当我这样做的时候,我得到了一个模糊的消息,很抱歉我不能在System.Xml.Serialization.TypeDesc.CheckSupported()附近做这个错误 XmlSerializer只能做一些琐碎的工作吗?还是我遗漏了什么?他们正在谈论MSDN。 下面是我的简化代码示例 using System; us

我有许多测试实现接口IDoTest的列表,我想将其存储在一个文件中。我还想从这个文件中读取

简单地使用XmlSerializer来存储我的IDoTest列表中的对象似乎很自然。但是当我这样做的时候,我得到了一个模糊的消息,很抱歉我不能在System.Xml.Serialization.TypeDesc.CheckSupported()附近做这个错误

XmlSerializer只能做一些琐碎的工作吗?还是我遗漏了什么?他们正在谈论MSDN。 下面是我的简化代码示例

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    public interface IDoTest
    {
        void DoTest();
        void Setup();
    }
    internal class TestDBConnection : IDoTest
    {
        public string DBName;
        public void DoTest()
        {
            Console.WriteLine("DoHardComplicated Test");
        }
        public void Setup()
        {
            Console.WriteLine("SetUpDBTest");
        }
    }
    internal class PingTest : IDoTest
    {
        public string ServerName;
        public void DoTest()
        {
            Console.WriteLine("MaybeDoAPing");
        }
        public void Setup()
        {
            Console.WriteLine("SetupAPingTest");
        }
    }     

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

            TestDBConnection Do1 = new TestDBConnection { DBName = "SQLDB" };
            PingTest Do2 = new PingTest { ServerName = "AccTestServ_5" };
            List<IDoTest> allTest = new List<IDoTest> { Do1, (Do2) };
            // Now I want to serialize my list. 
            // Its here where I get the error at allTest
            XmlSerializer x = new XmlSerializer(allTest.GetType());
            StreamWriter writer = new StreamWriter("mySerializedTestSuite.xml");
            x.Serialize(writer, allTest); 

        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Xml.Serialization;
命名空间控制台应用程序1
{
公共接口测试
{
void DoTest();
无效设置();
}
内部类TestDBConnection:IDoTest
{
公共字符串DBName;
公共空间DoTest()
{
控制台写入线(“Dohard复杂测试”);
}
公共作废设置()
{
控制台写入线(“SetUpDBTest”);
}
}
内部类测试:IDoTest
{
公共字符串ServerName;
公共空间DoTest()
{
Console.WriteLine(“MaybeDoAPing”);
}
公共作废设置()
{
Console.WriteLine(“SetupAPingTest”);
}
}     
内部课程计划
{
私有静态void Main(字符串[]args)
{
TestDBConnection Do1=newtestdbconnection{DBName=“SQLDB”};
PingTest Do2=新的PingTest{ServerName=“AccTestServ_5”};
List allTest=新列表{Do1,(Do2)};
//现在我想序列化我的列表。
//这就是我在allTest中得到错误的地方
XmlSerializer x=新的XmlSerializer(allTest.GetType());
StreamWriter=newstreamwriter(“mySerializedTestSuite.xml”);
x、 序列化(writer,allTest);
}
}
}

不确定这是否是问题的原因,但在这两个示例中,他们确实使用了
typeof(T)
而不是
T.GetType()


XmlSerializer
无法序列化
接口
,因此,它无法序列化某些接口的
列表
。它只能序列化具体的对象类型

假设您可能希望在某个时刻反序列化对象,并且如果它只输出与该接口相关的信息,则无法保证存在所有必要的数据来重建原始对象


如果您能够使用抽象基类并显式提供列表中可能出现的每种对象类型,则显示了一种潜在的解决方法。

我遵循了StriplingWarrior提供的链接,找到了这个极好的答案。从

我更改了他的实现,并创建了一个实现List和IXmlSerializable的类ListOfToDo。成功了! 这是我更改的代码

using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;

namespace ConsoleApplication1
{
    public interface IDoTest
    {
        void DoTest();
        void Setup();
    }
    public class TestDBConnection : IDoTest
    {
        public string DBName;
        public void DoTest()
        {
            Console.WriteLine("DoHardComplicated Test");
        }
        public void Setup()
        {
            Console.WriteLine("SetUpDBTest");
        }
    }
    public class PingTest : IDoTest
    {
        public string ServerName;
        public void DoTest()
        {
            Console.WriteLine("MaybeDoAPing");
        }
        public void Setup()
        {
            Console.WriteLine("SetupAPingTest");
        }
    }

    public class ListOfToDo : List<IDoTest>, **IXmlSerializable**
    {    
        #region IXmlSerializable
        public XmlSchema GetSchema(){ return null; }

        public void ReadXml(XmlReader reader)

           {
               reader.ReadStartElement("ListOfToDo");
               while (reader.IsStartElement("IDoTest"))
            {
                Type type = Type.GetType(reader.GetAttribute("AssemblyQualifiedName"));
                XmlSerializer serial = new XmlSerializer(type);

                reader.ReadStartElement("IDoTest");
                this.Add((IDoTest)serial.Deserialize(reader));
                reader.ReadEndElement(); //IDoTest
            }
            reader.ReadEndElement(); //IDoTest
        }

        public void WriteXml(XmlWriter writer)
        {
            foreach (IDoTest test in this)
            {
                writer.WriteStartElement("IDoTest");
                writer.WriteAttributeString("AssemblyQualifiedName", test.GetType().AssemblyQualifiedName);
                XmlSerializer xmlSerializer = new XmlSerializer(test.GetType());
                xmlSerializer.Serialize(writer, test);
                writer.WriteEndElement();
            }
        }
         #endregion
    }

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

            TestDBConnection Do1 = new TestDBConnection { DBName = "SQLDB" };
            PingTest Do2 = new PingTest { ServerName = "AccTestServ_5" };
            ListOfToDo allTest = new ListOfToDo { Do1, (Do2) };

            // Now I want to serialize my list. 
            // Its here where I get the error at allTest
            XmlSerializer x = new XmlSerializer(allTest.GetType());
            StreamWriter writer = new StreamWriter("mySerializedTestSuite.xml");
            x.Serialize(writer, allTest); 
            writer.Flush();
            writer.Close();

            //Read it aka deserialize
            {
                var xmlSerializer = new XmlSerializer(typeof(ListOfToDo));
                var xmlReader = XmlReader.Create(new StreamReader("mySerializedTestSuite.xml"));
                ListOfToDo readWhatToTest = (ListOfToDo)xmlSerializer.Deserialize(xmlReader);
                xmlReader.Close();
            }


        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Xml;
使用System.Xml.Schema;
使用System.Xml.Serialization;
命名空间控制台应用程序1
{
公共接口测试
{
void DoTest();
无效设置();
}
公共类TestDBConnection:IDoTest
{
公共字符串DBName;
公共空间DoTest()
{
控制台写入线(“Dohard复杂测试”);
}
公共作废设置()
{
控制台写入线(“SetUpDBTest”);
}
}
公共类测试:IDoTest
{
公共字符串ServerName;
公共空间DoTest()
{
Console.WriteLine(“MaybeDoAPing”);
}
公共作废设置()
{
Console.WriteLine(“SetupAPingTest”);
}
}
公共类ListOfToDo:List,**IXmlSerializable**
{    
#区域IXmlSerializable
公共XmlSchema GetSchema(){return null;}
公共void ReadXml(XmlReader)
{
reader.ReadStartElement(“ListOfToDo”);
while(reader.IsStartElement(“IDoTest”))
{
Type Type=Type.GetType(reader.GetAttribute(“AssemblyQualifiedName”);
XmlSerializer serial=新的XmlSerializer(类型);
reader.ReadStartElement(“IDoTest”);
this.Add((IDoTest)serial.Deserialize(reader));
reader.ReadEndElement();//IDoTest
}
reader.ReadEndElement();//IDoTest
}
public void WriteXml(XmlWriter)
{
foreach(本节中的IDoTest测试)
{
writer.writeStart元素(“IDoTest”);
writeAttributeTestRing(“AssemblyQualifiedName”,test.GetType().AssemblyQualifiedName);
XmlSerializer XmlSerializer=新的XmlSerializer(test.GetType());
serializer.Serialize(writer,test);
writer.writeedelement();
}
}
#端区
}
内部课程计划
{
私有静态void Main(字符串[]args)
{
TestDBConnection Do1=newtestdbconnection{DBName=“SQLDB”};
PingTest Do2=新的PingTest{ServerName=“AccTestServ_5”};
ListOfToDo allTest=新的ListOfToDo{Do1,(Do2)};
//现在我想序列化我的列表。
//这就是我在allTest中得到错误的地方
XmlSerializer x=新的XmlSerializer(allTest.GetType());
StreamWriter=newstreamwriter(“mySerializedTestSuite.xml”);
x、 序列化(writer,allTest);
writer.Flush();
writer.Close();
//读它或者反序列化
{
var xmlSerializer=新的xmlSerializer(typeof(ListOfToDo));
var xmlReader=xmlReader.Create(新的StreamReader(“mySerializedTestSuite.xml”);
    <?xml version="1.0" encoding="utf-8"?>
<ListOfToDo>
  <IDoTest AssemblyQualifiedName="ConsoleApplication1.TestDBConnection, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <TestDBConnection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <DBName>SQLDB</DBName>
    </TestDBConnection>
  </IDoTest>
  <IDoTest AssemblyQualifiedName="ConsoleApplication1.PingTest, ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <PingTest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <ServerName>AccTestServ_5</ServerName>
    </PingTest>
  </IDoTest>
</ListOfToDo>