2010-01-16 45 views
11

我有一个课程,我正在使用C#的序列号XmlSerializer。它标有XmlRoot属性,我想在派生类中继承此属性。XmlRootAttribute是可继承的吗?

查看文档,它并没有说XmlRoot设置继承为假使用AttributeUsageAttribute(继承应该默认为true),但是当试图反序列化我的继承类而没有XmlRoot属性时出现错误(“< rootNode xmlns =''>不是预期的。“)。

这个当前工作:

[Serializable()] 
[XmlRoot("rootNode")] 
public class BaseClass 
{ 
    [XmlAttribute("attributeA")] 
    public int A { get; set; } 
} 

[Serializable()] 
[XmlRoot("rootNode")] 
public class InheritedClass : BaseClass 
{ 
    [XmlElement("elementB")] 
    public int B { get; set; } 
} 

这是不行的,但我想要的东西:

[Serializable()] 
[XmlRoot("rootNode")] 
public class BaseClass 
{ 
    [XmlAttribute("attributeA")] 
    public int A { get; set; } 
} 

[Serializable()] 
public class InheritedClass : BaseClass 
{ 
    [XmlElement("elementB")] 
    public int B { get; set; } 
} 

的XML我可能会尝试反序列化作为InheritedClass看起来是这样的:

<rootNode attributeA="abc"> 
    <elementB>123</elementB> 
</rootNode> 

回答

21

Inherited只是表示属性可以被继承,而不是它是。例如,如果你看一下MemberInfo.GetCustomAttributes类型的签名,这是检索这些属性最常见的方式,它有这个过载:

public abstract Object[] GetCustomAttributes(bool inherit) 

如果参数inherittrue,则该方法将搜索的继承链,即它将查看基类或任何祖先类是否具有该属性,如果所查看的特定类型不具有该属性。为了使此方法在继承的类上找到属性,属性类本身不得设置AttributeUsage.Inherited = false

然而,如果属性的AttributeUsage.Inheritedtrue,该GetCustomAttributes方法仍然会忽略它,如果inherit参数为false

换句话说,AttributeUsage.Inherited许可,而不是一个要求。这完全取决于调用GetCustomAttributes(或类似的方法)来决定是否获得继承属性。你无法控制这一点。我相当肯定(不是100%肯定),XmlSerializer不寻找继承属性。

也许不是你寻找的答案,但你在那里;看起来你已经找到了解决方法。

顺便说一句,它在XML序列化中的工作方式是XmlSerializer使用XmlReflectionImporter,后者又得到XmlAttributes的实例。下面是构造函数是什么样子的XmlAttributes(反射出来的):

public XmlAttributes(ICustomAttributeProvider provider) 
{ 
    this.xmlElements = new XmlElementAttributes(); 
    this.xmlArrayItems = new XmlArrayItemAttributes(); 
    this.xmlAnyElements = new XmlAnyElementAttributes(); 
    object[] customAttributes = provider.GetCustomAttributes(false); 
    ... 
} 

所以你可以看到,它并事实上通过GetCustomAttributes方法;它确实是而不是寻找基类中的属性,即使这些属性是“可继承的”。“

+1

彻底的回应,我欣赏背景。谢谢! – 2010-01-16 03:30:32