是XmlRootAttribute可继承? [英] Is XmlRootAttribute inheritable?

查看:160
本文介绍了是XmlRootAttribute可继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,我用C#的<一个序列化href=\"http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlserializer.aspx\">XmlSerializer.这是标有<一个href=\"http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlrootattribute.aspx\">XmlRoot属性,我想在派生类中继承这个属性。

综观文档不说XmlRoot套继承假以AttributeUsageAttribute(继承应该默认为真),但尝试反序列化我的继承类没有XmlRoot属性(&LT时,我得到一个错误; rootNode中的xmlns =''方式&gt;。未预期的)

这当前工作:

  [序列化()]
[XmlRoot(rootNode中)]
公共类BaseClass的
{
    [XmlAttribute(attributeA)]
    公众诠释A {搞定;组; }
}[序列化()]
[XmlRoot(rootNode中)]
公共类InheritedClass:BaseClass的
{
    [XmlElement的(elementB)]
    公众诠释B {搞定;组; }
}

这是不行的,但是我想要什么:

  [序列化()]
[XmlRoot(rootNode中)]
公共类BaseClass的
{
    [XmlAttribute(attributeA)]
    公众诠释A {搞定;组; }
}[序列化()]
公共类InheritedClass:BaseClass的
{
    [XmlElement的(elementB)]
    公众诠释B {搞定;组; }
}

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

 &LT; rootNode中attributeA =ABC&GT;
    &所述; elementB&GT 123下; / elementB&GT;
&LT; / rootNode中&GT;


解决方案

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

 公共抽象对象[] GetCustomAttributes(布尔继承)

如果参数继承真正,则该方法将搜索继承链,也就是说,它会寻找到见如果基类或任何祖先类具有属性,如果特定类型被看不。为了让这个方法找到继承的类属性,属性类本身不能设置 AttributeUsage.Inherited = FALSE

但是,如果属性的 AttributeUsage.Inherited 真正 GetCustomAttributes 方法的仍然会忽略它,如果继承参数

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

也许不是你要找你的答案,但有;看起来你已经想出解决办法。

顺便说一下,它与XML序列化的方式是,的XmlSerializer 使用 XmlReflectionImporter 从而得到一个 XMLATTRIBUTES 的实例。下面是构造函数是什么样子的 XMLATTRIBUTES (反射出来的):

 公共XMLATTRIBUTES(ICustomAttributeProvider提供商)
{
    this.xmlElements =新XmlElementAttributes();
    this.xmlArrayItems =新XmlArrayItemAttributes();
    this.xmlAnyElements =新XmlAnyElementAttributes();
    [对象] customAttributes = provider.GetCustomAttributes(假);
    ...
}

所以,你可以看到,它实际上是通 GetCustomAttributes 方法;它的的寻找在基类的属性,即使这些属性是继承。

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>

解决方案

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."

这篇关于是XmlRootAttribute可继承?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆