2012-05-04 36 views
11

我遇到了一些在C#中使用XmlSerializer的令人惊讶的行为。考虑下面的一段代码。C#中的.NET XmlSerializer和嵌套类#

public class A : IEnumerable 
{ 
    public class B 
    { 
     [XmlAttribute] 
     public string PropA { get; set; } 
     [XmlElement] 
     public string PropB { get; set; } 
    } 

    public IEnumerator GetEnumerator() 
    { 
     yield break; 
    } 
} 

class Program 
{ 
    static void Main (string[] args) 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(A.B)); 

     XmlTextWriter writer = new XmlTextWriter(@"E:\temp\test.xml", Encoding.Default); 
     serializer.Serialize(writer, new A.B() { PropA = "one", PropB = "two" }); 
    } 
} 

在这个例子中,我试图序列嵌套类A·B,其本身不使用的容器类A的任何方式的一个实例。但是,当我试图建构XmlSerializer的吧,下面的异常被抛出:

InvalidOperationException异常是未处理:

要XML序列化,其自IEnumerable继承的类型必须 添加的实现(系统.Object)在其继承层次结构的所有级别。 Test.A不实现添加(System.Object)。

XmlSerializer试图对类型A应用序列化约束,当我实际尝试序列化类型A.B时。然而,我的理解是,除了在外部类型的实例中对数据的特权访问之外,嵌套类型并不是特殊的,并且其行为就像在名称空间中一样。

这是否理解不正确,做嵌套类型或XmlSerializer的语义证明这种行为,或者这是否感觉像XmlSerializer中的错误?

对于XmlSerializer语义,是否有任何文档化的需求在对嵌套类型应用时对所有外部类型强制执行XmlSerializer约束?

+1

您没有嵌套类型的问题。你的A类没有“B”类型的属性。 –

+0

另外,不要使用'new XmlTextWriter()'。自.NET 2.0以来,这已被弃用。改为使用'XmlWriter.Create()'。 –

+3

我很抱歉,但你完全错过了我的问题。我不是试图序列化A,而且我也不想将B序列化为A的属性。我试图序列化完全独立于A.并且我意识到TextWriter的弃用。这是我试图保持简短的一个人为的例子。 –

回答

0

这是在这里构成限制的IEnumerable。如果按照异常建议添加Add方法,则代码将正常工作。再次,这与XmlSerialization和IEnumerable的工作方式无关。如果我在这里,请纠正我。查询this 对此进行了很好的讨论。

+0

同样,我知道约束是什么,以及如何解决它。真正的问题是,为什么这个约束被应用到一个我实际上没有尝试序列化的类型。我观察到的另一个约束是一个问题,它是默认的构造函数,尽管我通过例子更难以隔离这个问题。 –

+0

贾斯廷是正确的。这是XML序列化程序中的一个错误。这与您所链接的问题不是同一个问题。 –

0

也许这是序列化运行时一个非常困难的问题,但我不对此行为有任何好的解释。我觉得IEnumerable的限制不适用于B类。