Действительно ли XmlRootAttribute является наследуемым?

У меня есть класс, который я сериализирую с XmlSerializer C#. Это отмечено с атрибутом XmlRoot, и я хотел бы наследовать этот атрибут в производном классе.

Рассмотрение документации, это не говорит, что наборы XmlRoot Наследовались ко лжи с AttributeUsageAttribute (Наследовались, как предполагается, принимает значение по умолчанию к истинному), но я получаю ошибку при попытке десериализовать мой наследованный класс без атрибута 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; }
}

XML я мог бы попытаться десериализовать как a InheritedClass похож на это:


    123

13
задан M. Dudley 16 January 2010 в 02:59
поделиться

1 ответ

Inherited правильно просто указывает, что атрибут может быть унаследованным, а не будет . Например, если вы посмотрите на сигнатуру типа для MemberInfo.GetCustomAttributes , который является наиболее распространенным способом получения этих атрибутов, у него будет следующая перегрузка:

public abstract Object[] GetCustomAttributes(bool inherit)

Если параметр наследует is true , то метод будет искать в цепочке наследования, то есть он будет искать, есть ли атрибут у базового класса или каких-либо классов-предков, если конкретный рассматриваемый тип его не имеет. Чтобы этот метод нашел атрибут в унаследованном классе, сам класс атрибута не должен устанавливать AttributeUsage.Inherited = false .

Однако, если атрибут AttributeUsage.Inherited имеет значение истина , метод GetCustomAttributes все равно будет игнорировать его, если наследует ] параметр 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 метод; он не ищет атрибуты в базовых классах, даже если эти атрибуты являются «наследуемыми».

25
ответ дан 1 December 2019 в 21:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: