14

C#のXmlSerializerでシリアル化するクラスがあります。XmlRoot属性でマークされているので、この属性を派生クラスに継承したいと思います。

ドキュメントを見ると、XmlRootがAttributeUsageAttributeを使用してInheritをfalseに設定するとは書かれていません(Inheritはデフォルトでtrueに設定されています)が、XmlRoot属性なしで継承されたクラスを逆シリアル化しようとするとエラーが発生します( "<rootNode xmlns ='' >は予期されていませんでした。」)。

これは現在機能します:

[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はInheritedClass次のようになります:

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

1 に答える 1

28

正しくはInherited、属性が継承できることを示すだけであり、継承されることを示すものではありません。たとえば、MemberInfo.GetCustomAttributesこれらの属性を取得する最も一般的な方法であるの型アノテーションを見ると、次のようなオーバーロードがあります。

public abstract Object[] GetCustomAttributes(bool inherit)

パラメータinherittrue、の場合、メソッドは継承チェーンを検索します。つまり、調べている特定のタイプに属性がない場合は、基本クラスまたは祖先クラスに属性があるかどうかを調べます。このメソッドが継承されたクラスの属性を見つけるためには、属性クラス自体がを設定してはなりませんAttributeUsage.Inherited = false

ただし、属性AttributeUsage.Inheritedが。の場合、パラメータがtrue。の場合、GetCustomAttributesメソッドはそれを無視します。inheritfalse

つまり、これAttributeUsage.Inherited許可であり、要件ではありません。GetCustomAttributes継承された属性を取得するかどうかを決定するのは、完全に誰が呼び出すか(または同様のメソッド)です。これを制御することはできません。XmlSerializerが継承された属性を検索しないことはかなり確信しています(100%ポジティブではありません) 。

たぶんあなたが探していた答えではないかもしれませんが、あなたはそこにいます。回避策はすでにわかっているようです。

ちなみに、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ません。

于 2010-01-16T03:18:43.937 に答える