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" });
    }
}

在这个例子中,我尝试序列化嵌套类 AB 的一个实例,它本身并没有以任何方式使用容器类 A。但是当我尝试为其构造 XmlSerializer 时,会引发以下异常:

InvalidOperationException 未处理:

要实现 XML 可序列化,从 IEnumerable 继承的类型必须在其继承层次结构的所有级别上都有 Add(System.Object) 的实现。Test.A 没有实现 Add(System.Object)。

XmlSerializer 正在尝试对 A 类型应用序列化约束,而我实际上是在尝试序列化类型 AB 但是我的理解是,除了对外部类型实例中的数据的特权访问之外,嵌套类型并不特殊,并且表现得好像它是在命名空间中。

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

具体到 XmlSerializer 语义,是否有任何书面要求在应用于嵌套类型时对所有外部类型强制执行 XmlSerializer 约束?

4

4 回答 4

1

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

因为嵌套类型被视为声明类型的成员,所以嵌套类型可以访问声明类型中的所有其他成员。

因此,如果序列化程序想要使用 AB,它也需要 A 的定义。IEnumerable 验证开始的地方。

没关系 B 实际上没有引用 A 中的任何内容 :)

于 2013-06-13T20:38:27.490 回答
0

在这里提出约束的是 IEnumerable。如果您按照异常的建议添加 Add 方法,您的代码将正常工作。同样,这与 XmlSerialization 关系不大,更多的是与 IEnumerable 的工作方式有关。如果我不在这里,请纠正我。检查this 以获得相同的良好讨论。

于 2012-05-04T10:11:10.223 回答
0

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

于 2013-07-25T15:08:59.243 回答
0

XmlSerializer 对实现 IEnumerable 或 ICollection 的类进行特殊处理。

更多细节在这里: XmlSerializer 和 IEnumerable:序列化可能没有无参数构造函数:错误?

于 2013-03-07T11:01:39.350 回答