2012-10-26 73 views
0

對於當前的項目,我試圖讓一個通用的XML創建者使用XmlSerializer類 - 我需要某個類中的某個元素根據類型設置ElementName創作者在這個上下文中足夠簡單的類。這裏有一個例子:來自通用類中的T的XML元素名稱

public abstract class ElementTypeBase 
    { 
    public abstract string ElementName { get; } 
    } 
    public class ElementTypeA : ElementTypeBase 
    { 
    public override string ElementName 
    { 
     get { return "ElementA"; } 
    } 
    } 

然後它傳遞給將被用於XmlSerializerXML對象類,但我想ElementName具體到類型。

public class XMLObject<T> where T : ElementTypeBase 
    { 
    [XmlElement(Activator.CreateInstance<T>().ElementName)] 
    public string SomeElement; 
    } 

我想我能做到這一點,但得到:

的屬性參數必須是常量表達式的typeof屬性參數類型的表達 或數組創建表達式

所以我認爲我可以override ToString()但這不起作用,我想使用常量,但它感覺很髒。還有其他建議嗎?

+0

這聽起來像一個奇怪的方法。爲什麼使用'XmlSerializer'註解,如果XML結構是動態的呢? – millimoose

+0

@millimoose這是需要動態構建的整個主機結構中的一個元素,我可以爲每種不同類型創建一個類,但嘗試使其儘可能通用。 編輯:當我說我的意思是strucutre不需要是動態的這個XML,但對於一個elemenet它確實需要是因爲該單個元素可以有不同的屬性,顯然將需要一個不同的元素名稱 - 休息仍然是一樣的(不知道我已經解釋得如何...) – LukeHennerley

+0

該文檔提到你可以重寫['IXmlSerializable'](http://msdn.microsoft.com/en-us/library/system。 xml.serialization.ixmlserializable.aspx)自定義XML序列化,在ElementTypeBase上這樣做似乎是實現你想要的簡單方法。 – millimoose

回答

0

您可以通過XmlAttributeOverrides類來完成,如下所示。 但是,您需要緩存XmlSerializer實例,我不會爲您的問題推薦此方法。

當你說你有一個對每個繼承對象都不同的元素時,我建議把這個元素放在繼承類中,而不是普通類中,並且對它的XmlElement.ElementName進行硬編碼。

using System; 
using System.Xml.Serialization; 

public class Program 
{ 
    static void Main(string[] args) 
    { 
     XmlSerializer serializer = 
      new XmlSerializer(typeof(XMLObject<MyElement>), 
       XMLObject<MyElement>.Overrides); 
     serializer.Serialize(Console.Out, 
      new XMLObject<MyElement>() { SomeElement = "value" }); 
     Console.ReadLine(); 
    } 
} 
public class XMLObject<T> where T : ElementTypeBase, new() 
{ 
    public static XmlAttributeOverrides Overrides { get; private set; } 
    static XMLObject() 
    { 
     Overrides = new XmlAttributeOverrides(); 
     Overrides.Add(typeof(XMLObject<T>), "SomeElement", 
      new XmlAttributes 
      { 
       XmlElements = 
       { 
        new XmlElementAttribute(new T().ElementName) 
       } 
      }); 
    } 

    public string SomeElement { get; set; } 
} 
public abstract class ElementTypeBase 
{ 
    public abstract string ElementName { get; } 
} 
public class MyElement : ElementTypeBase 
{ 
    public override string ElementName 
    { 
     get { return "ElementA"; } 
    } 
} 
+0

通過向我介紹XmlAttributeOverrides,你讓我瞭解了一半,結果並不像我的例子那麼複雜,但無論如何感謝。 – LukeHennerley

+0

正如我在答案中概述的那樣,即使這是可行的,但您的問題是更多地指出設計缺陷而不是技術問題。很高興你自己做到了。 – Paciv

相關問題