【问题标题】:.NET XmlSerializer and nested classes in C#.NET XmlSerializer 和 C# 中的嵌套类
【发布时间】:2012-05-04 02:35:18
【问题描述】:

我在 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 未处理:

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

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

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

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

【问题讨论】:

  • 嵌套类型没有问题。您的 A 类没有 B 类型的属性。
  • 另外,不要使用new XmlTextWriter()。自 .NET 2.0 以来,这已被弃用。请改用XmlWriter.Create()
  • 很抱歉,您完全错过了我的问题的重点。我没有尝试序列化 A,也没有尝试将 B 序列化为 A 的属性。我试图完全独立于 A 来序列化它。而且我知道 TextWriter 已被弃用。这是一个人为的例子,我试图保持简短。
  • +1 这对我来说就像一个错误。

标签: c# .net xmlserializer nested-class


【解决方案1】:

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

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

所以如果序列化器想要使用 A.B,它也需要 A 的定义。 IEnumerable 验证开始的地方。

B 实际上没有引用 A 中的任何内容并不重要 :)

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 再次,我知道约束是什么,以及如何解决它。真正的问题是,为什么要将此约束应用于我实际上并未尝试序列化的类型。我观察到的另一个问题是默认构造函数,尽管我很难通过示例来隔离它。
    • 贾斯汀是正确的。这是 XML 序列化程序中的一个错误。这与您链接的问题不同。
    【解决方案3】:

    XmlSerializer 对实现 IEnumerable 或 ICollection 的类给予特殊处理。

    更多细节在这里: XmlSerializer and IEnumerable: Serialization possible w/o parameterless constructor: Bug?

    【讨论】:

    • 我提供的例子的重点是实现 IEnumerable 的类实际上并不是被序列化的类。嵌套类正在被序列化,并且是完全独立的。您链接的问题的已接受答案的作者似乎也同意这是一个错误。
    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-05
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 2017-02-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多