2010-01-16 43 views
11

我有一個課程,我正在使用C#的序列號XmlSerializer。它標有XmlRoot屬性,我想在派生類中繼承此屬性。XmlRootAttribute是可繼承的嗎?

查看文檔,它並沒有說XmlRoot設置繼承爲假使用AttributeUsageAttribute(繼承應該默認爲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> 

回答

21

Inherited只是表示屬性可以被繼承,而不是它是。例如,如果你看一下MemberInfo.GetCustomAttributes類型的簽名,這是檢索這些屬性最常見的方式,它有這個過載:

public abstract Object[] GetCustomAttributes(bool inherit) 

如果參數inherittrue,則該方法將搜索的繼承鏈,即它將查看基類或任何祖先類是否具有該屬性,如果所查看的特定類型不具有該屬性。爲了使此方法在繼承的類上找到屬性,屬性類本身不得設置AttributeUsage.Inherited = false

然而,如果屬性的AttributeUsage.Inheritedtrue,該GetCustomAttributes方法仍然會忽略它,如果inherit參數爲false

換句話說,AttributeUsage.Inherited許可,而不是一個要求。這完全取決於調用GetCustomAttributes(或類似的方法)來決定是否獲得繼承屬性。你無法控制這一點。我相當肯定(不是100%肯定),XmlSerializer不尋找繼承屬性。

也許不是你尋找的答案,但你在那裏;看起來你已經找到了解決方法。

順便說一句,它在XML序列化中的工作方式是XmlSerializer使用XmlReflectionImporter,後者又得到XmlAttributes的實例。下面是構造函數是什麼樣子的XmlAttributes(反射出來的):

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

所以你可以看到,它並事實上通過GetCustomAttributes方法;它確實是而不是尋找基類中的屬性,即使這些屬性是「可繼承的」。「

+1

徹底的迴應,我欣賞背景。謝謝! – 2010-01-16 03:30:32