XmlRootAttribute 是否可继承?
我有一个类,正在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Inherited
正确地仅指示该属性可以被继承,而不是它将被继承。例如,如果您查看MemberInfo.GetCustomAttributes
的类型签名(这是检索这些属性的最常见方法),它具有以下重载:如果参数
inherit
是true
,则该方法将搜索继承链,即,如果正在查看的特定类型没有,则它将查看基类或任何祖先类是否具有该属性。为了使此方法在继承类上查找属性,属性类本身不得设置 AttributeUsage.Inherited = false。但是,如果属性的
AttributeUsage.Inherited
为true
,则GetCustomAttributes
方法仍将忽略它(如果inherit
)。 code> 参数为false
。换句话说,
AttributeUsage.Inherited
是一个权限,而不是要求。是否获取继承属性完全取决于谁调用GetCustomAttributes
(或类似方法)。你无法控制这个。我相当确定(不是 100% 肯定)XmlSerializer 不会查找继承的属性。也许不是您正在寻找的答案,但您就在那里;看起来您已经找到了解决方法。
顺便说一句,它处理 XML 序列化的方式是
XmlSerializer
使用XmlReflectionImporter
,而后者又获取XmlAttributes
的实例。以下是XmlAttributes
的构造函数(在 Reflector 之外):因此您可以看到它实际上将 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 forMemberInfo.GetCustomAttributes
, which is the most common way to retrieve these attributes, it has this overload:If the parameter
inherit
istrue
, 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 setAttributeUsage.Inherited = false
.However, if the attribute's
AttributeUsage.Inherited
istrue
, theGetCustomAttributes
method will still ignore it if theinherit
parameter isfalse
.In other words,
AttributeUsage.Inherited
is a permission, not a requirement. It is completely up to whomever invokesGetCustomAttributes
(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 theXmlSerializer
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 theXmlReflectionImporter
which in turn gets an instance ofXmlAttributes
. Here is what the constructor looks like forXmlAttributes
(out of Reflector):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."