У меня есть класс, который я сериализирую с 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
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
метод; он не ищет атрибуты в базовых классах, даже если эти атрибуты являются «наследуемыми».