2010-01-16 19 views
11

Tengo una clase que estoy serializando con C# XmlSerializer. Está marcado con el atributo XmlRoot, y me gustaría heredar este atributo en una clase derivada.¿XmlRootAttribute es heredable?

En cuanto a la documentación que no dice que los conjuntos de XmlRoot heredan a falso con AttributeUsageAttribute (Heredar se supone que por defecto a true), pero me da un error al intentar deserializar mi clase heredada sin un atributo XmlRoot (" < rootNode xmlns = '' > no se esperaba. ").

Esto funciona actualmente:

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

Esto no funciona, pero es lo que quiero:

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

El XML que podría intentar deserializar como InheritedClass se parece a esto:

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

Respuesta

21

Inherited propertly simplemente indica que el atributo puede ser heredado, no es que será ser. Por ejemplo, si nos fijamos en la firma tipo para MemberInfo.GetCustomAttributes, que es la forma más común de recuperar estos atributos, tiene esta sobrecarga:

public abstract Object[] GetCustomAttributes(bool inherit) 

Si el parámetro inherit es true, entonces el método de búsqueda de la herencia cadena, es decir, verá si la clase base o cualquier clase antecesora tienen el atributo, si el tipo específico que se mira no lo hace. Para que este método encuentre un atributo en una clase heredada, la clase de atributo en sí no debe establecer AttributeUsage.Inherited = false.

Sin embargo, si el atributo de AttributeUsage.Inherited es true, el método GetCustomAttributestodavía se ignoran si el parámetro es inheritfalse.

En otras palabras, es un permiso AttributeUsage.Inherited, no es un requisito. Todo depende de quien invoca GetCustomAttributes (o un método similar) para decidir si se obtienen atributos heredados o no. No puedes controlar esto. Estoy bastante seguro (no es 100% positivo) de que el XmlSerializer no busca atributos heredados.

Quizás no sea la respuesta que estabas buscando, pero ahí estás; parece que ya has descubierto la solución.

Por cierto, la forma en que funciona con la serialización XML es que el XmlSerializer utiliza el que a su vez obtiene una instancia de XmlAttributes. Esto es lo que el constructor se parece a XmlAttributes (fuera del reflector):

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

Así se puede ver que no los haya pasado falsa al método GetCustomAttributes; sí no busca atributos en clases base, incluso si esos atributos son "heredables"."

+1

Respuesta completa, agradezco el fondo. ¡Gracias! –

Cuestiones relacionadas