2012-04-04 49 views
12

可能重复:
How to serialize an IList<T>?如何序列化的接口,如IList的<T>

我想序列化的类(姑且称之为S),其中包含的类型IList<T>的属性T是我定义的另一个类。当我试图将S类的实例序列化为XML时,我得到一个异常。这是可以理解的,因为XmlSerializer不知道要使用哪个具体类。有没有办法,希望使用属性来指定在序列化/反序列化实例时要实例化哪个具体类。我的S类的实现创建了List<T>类的实例。下面是一些代码来说明我的例子:

using System; 
using System.Xml.Serialization; 
using System.IO; 

[Serializable] 
public class T { } 

[Serializable] 
public class S 
{ 
    public IList<T> ListOfTs { get; set; } 

    public S() 
    { 
     ListOfTs = new List<T>(); 
    } 
} 

public class Program 
{ 
    public void Main() 
    { 
     S s = new S(); 
     s.ListOfTs.Add(new T()); 
     s.ListOfTs.Add(new T()); 
     XmlSerializer serializer = new XmlSerializer(typeof(S)); 
     serializer.Serialize(new StringWriter(), s); 
    } 
} 

我希望有我可以把上面的ListOfTs定义,在连载说的属性,“序列化/反序列化时假设的List<T>的实例”。

回答

11

更改

public IList<T> ListOfTs { get; set; } 

public List<T> ListOfTs { get; set; } 

然后它会奏效。

+3

我会这样做,除了这会改变'S'类的接口。虽然这不太可能产生实际影响,但从原则上讲,我想看看是否有办法在不改变类型的情况下解决问题。 – 2012-04-04 14:16:30

+0

建议的解决方案虽然是工作的,但可能会破坏您的公共API架构 – bashis 2015-09-22 18:15:24

0

您可以实现IXmlSerializable接口并使用Xml读取器和编写器手动实现序列化逻辑。

2

我认为这种问题通常有两种方法。

其中一个将使用DataContractSerializer,但由于您已经在使用XmlSerializer,因此您可能不想这样做。

“替代”是为了序列化而专门使用的属性,并且在序列化期间忽略IList。

[Serializable] 
public class S 
{ 
    IList<T> _listofTs; 

    [XmlIgnore] 
    public IList<T> ListOfTs { get _listofTs; set _listofTs = value; } 

    [XmlElement(Name="Not Exactly the Greatest Solution!")] 
    public List<T> ListOfTs { get _listofTs; set _listofTs = value; } 

    public S() 
    { 
     ListOfTs = new List<T>(); 
    } 
} 
+0

在属性上使用XmlIgnore属性将完全忽略它。问题是在序列化中包含接口属性。 – 2012-04-04 15:45:28