通用类中T的XML元素名称

时间:2012-10-26 13:19:40

标签: c# xml generics inheritance

对于我正在尝试使用XML类创建一个通用XmlSerializer创建者的当前项目 - 我需要其中一个类中的某个元素才能设置ElementName关于创建者在此上下文中所处类的类型,这很简单。这是一个例子:

  public abstract class ElementTypeBase
  {
    public abstract string ElementName { get; }
  }
  public class ElementTypeA : ElementTypeBase
  {
    public override string ElementName
    {
      get { return "ElementA"; }
    }
  }

然后将其传递给我的XML对象类,该对象类将用于XmlSerializer,但我希望ElementName特定于该类型。

  public class XMLObject<T> where T : ElementTypeBase
  {
    [XmlElement(Activator.CreateInstance<T>().ElementName)]
    public string SomeElement;
  }

我以为我能够做到这一点但得到:

  

属性参数必须是常量表达式,typeof表达式   或属性参数类型

的数组创建表达式

所以我认为我可以override ToString()但是这不起作用,我在考虑使用常量但感觉很脏。还有其他建议吗?

1 个答案:

答案 0 :(得分:0)

您可以通过XmlAttributeOverrides类执行此操作,如下所示。 但是,您需要缓存XmlSerializer实例,我不会为您的问题推荐这种方法。

当你说每个继承对象有一个不同的元素时,我建议将这个元素放在继承的类中,而不是通用的,并对其XmlElement.ElementName进行硬编码。

using System;
using System.Xml.Serialization;

public class Program
{
    static void Main(string[] args)
    {
        XmlSerializer serializer =
            new XmlSerializer(typeof(XMLObject<MyElement>),
                XMLObject<MyElement>.Overrides);
        serializer.Serialize(Console.Out,
            new XMLObject<MyElement>() { SomeElement = "value" });
        Console.ReadLine();
    }
}
public class XMLObject<T> where T : ElementTypeBase, new()
{
    public static XmlAttributeOverrides Overrides { get; private set; }
    static XMLObject()
    {
        Overrides = new XmlAttributeOverrides();
        Overrides.Add(typeof(XMLObject<T>), "SomeElement",
            new XmlAttributes
            {
                XmlElements =
                {
                    new XmlElementAttribute(new T().ElementName)
                }
            });
    }

    public string SomeElement { get; set; }
}
public abstract class ElementTypeBase
{
    public abstract string ElementName { get; }
}
public class MyElement : ElementTypeBase
{
    public override string ElementName
    {
        get { return "ElementA"; }
    }
}