c# - 如何动态添加 XmlInclude 属性

标签 c# .net xml-serialization xmlinclude

我有以下类(class)

[XmlRoot]
public class AList
{
   public List<B> ListOfBs {get; set;}
}

public class B
{
   public string BaseProperty {get; set;}
}

public class C : B
{
    public string SomeProperty {get; set;}
}

public class Main
{
    public static void Main(string[] args)
    {
        var aList = new AList();
        aList.ListOfBs = new List<B>();
        var c = new C { BaseProperty = "Base", SomeProperty = "Some" };
        aList.ListOfBs.Add(c);

        var type = typeof (AList);
        var serializer = new XmlSerializer(type);
        TextWriter w = new StringWriter();
        serializer.Serialize(w, aList);
    }    
}

现在,当我尝试运行代码时,我在最后一行得到了一个 InvalidOperationException

XmlTest.C 类型不是预期的。使用 XmlInclude 或 SoapInclude 属性指定静态未知的类型。

我知道在 [XmlRoot] 中添加 [XmlInclude(typeof(C))] 属性可以解决问题。但我想动态地实现它。因为在我的项目中,类 C 在加载之前是未知的。 C 类作为插件加载,因此我无法在其中添加 XmlInclude 属性。

我也试过

TypeDescriptor.AddAttributes(typeof(AList), new[] { new XmlIncludeAttribute(c.GetType()) });

之前

var type = typeof (AList);

但是没有用。它仍然给出相同的异常。

有没有人知道如何实现它?

最佳答案

两种选择;最简单的(但给出奇怪的 xml)是:

XmlSerializer ser = new XmlSerializer(typeof(AList),
    new Type[] {typeof(B), typeof(C)});

示例输出:

<AList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <ListOfBs>
    <B />
    <B xsi:type="C" />
  </ListOfBs>
</AList>

比较优雅的是:

XmlAttributeOverrides aor = new XmlAttributeOverrides();
XmlAttributes listAttribs = new XmlAttributes();
listAttribs.XmlElements.Add(new XmlElementAttribute("b", typeof(B)));
listAttribs.XmlElements.Add(new XmlElementAttribute("c", typeof(C)));
aor.Add(typeof(AList), "ListOfBs", listAttribs);

XmlSerializer ser = new XmlSerializer(typeof(AList), aor);

示例输出:

<AList xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <b />
  <c />
</AList>

无论哪种情况,您必须缓存并重新使用ser实例;否则你会因动态编译而大量消耗内存。

关于c# - 如何动态添加 XmlInclude 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2689566/

相关文章:

c# - bool类型返回规则

.net - .NET 应用程序如何与 32 位和 64 位 Office 一起运行?

c# - 在自定义类的 IEnumerable 中对具有特定 ID 的项目求和

c# - IEnumerable Count() 和 Length 之间的区别

c# - 在 C# 中 XML 反序列化后如何重建对象层次结构/引用

C# 生成新任务

c# - 按钮未按要求触发

c# - C# 中基本操作的成本是多少?

c# - 使用命名空间将类序列化为 XML

xml-serialization - 如何使用 XStream 有条件地序列化字段(属性)