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