XmlRootAttribute 是否可继承?

发布于 2024-08-17 16:22:19 字数 1266 浏览 1 评论 0原文

我有一个类,正在使用 C# 的 XmlSerializer。它标有 XmlRoot 属性,并且我想在派生类中继承这个属性。

查看文档,它并没有说 XmlRoot 使用 AttributeUsageAttribute 将 Inherit 设置为 false(Inherit 应该默认为 true),但是在尝试反序列化没有 XmlRoot 属性的继承类时出现错误(“是没有预料到的。”)。

这目前有效:

[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; }
}

我可能尝试反序列化为 InheritedClass 的 XML 如下所示:

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

I have a class I am serializing with C#'s XmlSerializer. It is marked with the XmlRoot attribute, and I would like to inherit this attribute in a derived class.

Looking at the documentation it does not say that XmlRoot sets Inherit to false with AttributeUsageAttribute (Inherit is supposed to default to true), but I get an error when trying to deserialize my inherited class without an XmlRoot attribute ("<rootNode xmlns=''> was not expected.").

This currently works:

[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; }
}

This does not work, but is what I want:

[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; }
}

The XML I might try to deserialize as a InheritedClass looks like this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

想挽留 2024-08-24 16:22:19

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

public abstract Object[] GetCustomAttributes(bool inherit)

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

但是,如果属性的 AttributeUsage.Inheritedtrue,则 GetCustomAttributes 方法仍将忽略它(如果 inherit)。 code> 参数为 false

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

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

顺便说一句,它处理 XML 序列化的方式是 XmlSerializer 使用 XmlReflectionImporter,而后者又获取 XmlAttributes 的实例。以下是 XmlAttributes 的构造函数(在 Reflector 之外):

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

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

The Inherited propertly merely indicates that the attribute can be inherited, not that it will be. For example, if you look at the type signature for MemberInfo.GetCustomAttributes, which is the most common way to retrieve these attributes, it has this overload:

public abstract Object[] GetCustomAttributes(bool inherit)

If the parameter inherit is true, then the method will search the inheritance chain, i.e. it will look to see if the base class or any ancestor classes have the attribute, if the specific type being looked at does not. In order for this method to find an attribute on an inherited class, the attribute class itself must not set AttributeUsage.Inherited = false.

However, if the attribute's AttributeUsage.Inherited is true, the GetCustomAttributes method will still ignore it if the inherit parameter is false.

In other words, AttributeUsage.Inherited is a permission, not a requirement. It is completely up to whomever invokes GetCustomAttributes (or a similar method) to decide whether or not to obtain inherited attributes. You can't control this. I'm fairly certain (not 100% positive) that the XmlSerializer does not look for inherited attributes.

Maybe not the answer you were looking for, but there you are; looks like you've already figured out the workaround.

Incidentally, the way it works with XML serialization is that the XmlSerializer uses the XmlReflectionImporter which in turn gets an instance of XmlAttributes. Here is what the constructor looks like for XmlAttributes (out of Reflector):

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

So you can see that it does in fact pass false to the GetCustomAttributes method; it does not look for attributes in base classes, even if those attributes are "inheritable."

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文