14

我有一个使用 C# 的XmlSerializer序列化的类。它标有XmlRoot属性,我想在派生类中继承此属性。

查看文档并没有说 XmlRoot 使用 AttributeUsageAttribute 将 Inherit 设置为 false(Inherit 应该默认为 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; }
}

我可能尝试反序列化的 XMLInheritedClass如下所示:

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

1 回答 1

28

Inherited仅表示该属性可以继承,而不是它将被继承。例如,如果您查看 的类型签名MemberInfo.GetCustomAttributes,这是检索这些属性的最常用方法,它具有以下重载:

public abstract Object[] GetCustomAttributes(bool inherit)

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

但是,如果属性AttributeUsage.Inherited是,如果参数是trueGetCustomAttributes方法仍然会忽略它。inheritfalse

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

也许不是您正在寻找的答案,但您在那儿;看起来你已经想出了解决方法。

顺便说一句,它与 XML 序列化一起工作的方式是XmlSerializer使用. 这是构造函数的样子(在反射器之外):XmlReflectionImporterXmlAttributesXmlAttributes

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

所以你可以看到它实际上确实将false传递给了GetCustomAttributes方法;它不会基类中查找属性,即使这些属性是“可继承的”。

于 2010-01-16T03:18:43.937 回答