C#中的.NET XmlSerializer和嵌套类

11

我在使用C#中的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 was unhandled:”
“To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy. Test.A does not implement Add(System.Object).”
XmlSerializer正试图针对类型A应用序列化约束,而我实际上正在尝试序列化类型A.B。然而,我的理解是,除了可以特权地访问外部类型的实例数据之外,嵌套类型并没有什么特别之处,并且表现得好像它在命名空间中一样。
这个理解是不正确的吗?嵌套类型或XmlSerializer的语义是否可以证明这种行为,还是这感觉像是XmlSerializer中的一个错误?
具体关于XmlSerializer的语义,是否有任何记录的要求,在应用于嵌套类型时强制执行XmlSerializer约束的所有外部类型?

1
你的嵌套类型没有问题。你的A类没有一个类型为'B'的属性。 - John Saunders
另外,不要使用 new XmlTextWriter()。自 .NET 2.0 起已被弃用。请改用 XmlWriter.Create() - John Saunders
3
抱歉,您完全没有理解我的问题。我不是试图将A序列化,也不是将B作为A的属性进行序列化。我尝试将其完全独立于A进行序列化。我知道TextWriter已被弃用。这只是我脑海中构思的一个例子,我试图保持简洁。 - Justin Aquadro
2
+1 这对我来说感觉像是一个 bug。 - phoog
4个回答

1

http://msdn.microsoft.com/en-us/library/vstudio/ms229027%28v=vs.100%29.aspx

由于嵌套类型被视为声明类型的成员,因此嵌套类型可以访问声明类型中的所有其他成员。
因此,如果序列化程序想要使用A.B,则还需要A的定义。这就是IEnumerable验证发挥作用的地方。
无论B是否实际上引用了A中的任何内容都没有关系 :)

0

问题出在IEnumerable上。如果按照异常提示添加Add方法,你的代码就能正常工作了。这与XmlSerialization关系不大,更多地是与IEnumerable的工作方式有关。如果我说错了,请纠正我。可以查看this以获取相关讨论。


我知道约束是什么,以及如何解决它。真正的问题是,为什么这个约束被应用于我实际上并没有尝试序列化的类型。另一个我观察到的问题是默认构造函数,但是通过示例隔离它更加困难。 - Justin Aquadro
Justin是正确的。这是XML序列化器中的一个错误。这不是您链接的相同问题。 - John Saunders

0

可能这是序列化运行时中非常困难的问题,但我没有任何对这种行为的好解释。我感觉 IEnumerable 的限制不适用于类 B。


0

我提供的示例的重点是实现IEnumerable接口的类实际上并不是被序列化的类。嵌套类正在被序列化,并且是完全独立的。您链接的问题的被采纳答案的作者似乎也认为这是一个错误。 - Justin Aquadro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接