2011-02-11 18 views
9

有人可以向我解釋爲什麼第一個示例將序列化爲XML,第二個將拋出有關嘗試將所有類型轉換爲對方的運行時錯誤?如果我從第二個示例中刪除了XmlElement屬性,它將會序列化,但XML元素名稱將會出錯(「Item」而不是爲其類型指定的屬性)。第一個片段是使用模式文件從XSD工具生成的。通用屬性的序列化

更好的是,有沒有辦法讓這個工作?我更喜歡使用通用類型來投射/從對象。它使得代碼更簡潔。明確地轉換對象表明您的設計存在問題。

public partial class OAIPMHtype 
{ 
    private object itemsField; 

    [XmlElement("GetRecord", typeof(GetRecordType))] 
    [XmlElement("Identify", typeof(IdentifyType))] 
    [XmlElement("ListIdentifiers", typeof(ListIdentifiersType))] 
    [XmlElement("ListMetadataFormats", typeof(ListMetadataFormatsType))] 
    [XmlElement("ListRecords", typeof(ListRecordsType))] 
    [XmlElement("ListSets", typeof(ListSetsType))] 
    [XmlElement("error", typeof(OAIPMHerrorType))] 
    public object Item 
    { 
     get { return this.itemsField; } 
     set { this.itemsField = value; } 
    } 
} 

這不會序列化。

public class OaiPmh<T> 
{ 
    private T itemsField; 

    [XmlElement("GetRecord", typeof(GetRecordType))] 
    [XmlElement("Identify", typeof(IdentifyType))] 
    [XmlElement("ListIdentifiers", typeof(ListIdentifiersType))] 
    [XmlElement("ListMetadataFormats", typeof(ListMetadataFormatsType))] 
    [XmlElement("ListRecords", typeof(ListRecordsType))] 
    [XmlElement("ListSets", typeof(ListSetsType))] 
    [XmlElement("error", typeof(OAIPMHerrorType))] 
    public T Item 
    { 
     get { return itemsField; } 
     set { itemsField = value; } 
    } 
} 

,併爲進一步澄清,我曾嘗試創建XmlSerializer對象時指定的所有額外的類型,並沒有幫助。

這就是會拋出的異常:

Unable to generate a temporary class (result=1). 
error CS0030: Cannot convert type 'ErrorRequest' to 'GetRecordRequest' 
error CS0030: Cannot convert type 'ErrorRequest' to 'ListRecordsRequest' 
error CS0030: Cannot convert type 'ErrorRequest' to 'IdentityRequest' 
error CS0030: Cannot convert type 'ErrorRequest' to 'ListSetsRequest' 
error CS0030: Cannot convert type 'ErrorRequest' to 'ListIdentifiersRequest' 
error CS0030: Cannot convert type 'ErrorRequest' to 'ListMetadataFormatsRequest' 
error CS0029: Cannot implicitly convert type 'ListSetsRequest' to 'ErrorRequest' 
error CS0029: Cannot implicitly convert type 'ListIdentifiersRequest' to 'ErrorRequest' 
error CS0029: Cannot implicitly convert type 'ListMetadataFormatsRequest' to 'ErrorRequest' 
error CS0029: Cannot implicitly convert type 'GetRecordRequest' to 'ErrorRequest' 
error CS0029: Cannot implicitly convert type 'ListRecordsRequest' to 'ErrorRequest' 
error CS0029: Cannot implicitly convert type 'IdentityRequest' to 'ErrorRequest 

'

它種有意義與泛型類型,眼看類型是如何具體結合在編譯時。但看到它如何與對象引用一起工作,在我看來,它也應該使用泛型類型。

+0

什麼是拋出的異常? – 2011-02-11 19:32:50

+0

謝謝,我會編輯。 – MonkeyWrench 2011-02-11 19:38:44

+0

什麼是'ErrorRequest`? – 2011-02-11 20:20:04

回答

2

我認爲CS0029 compiler error page on MSDN提供您正在尋找的信息。

根據我如何閱讀本文,您的第一個示例工作,因爲您的班級中沒有發生轉換。由於您的明確性在傳遞Object,因此不需要進行任何轉換,也不會引發編譯器錯誤。

在第二個示例中,直到運行時才知道類型。通過指定多個XmlElement屬性,編譯器認爲所有這些類型都必須是可互換的。但是,由於您沒有爲這些提供明確的轉換,因此編譯器擔心這兩種類型之間的轉換可能會縮小轉換範圍並引發錯誤。

2

你看過Generics FAQ頁面下的「如何序列化泛型」問題?它可以幫助你。

0

不同類型的不同序列化元素的唯一方法是使用objectIXmlSerializable

不幸的是,XmlSerializer無法訪問非公共屬性。因此通過第二個公開屬性公開object項目允許序列化。我不會在實際情況下使用它:

[XmlElement("GetRecord", typeof(GetRecordType))] 
[XmlElement("Identify", typeof(IdentifyType))] 
public object ItemSerializer 
{ 
    get { return this.Item; } 
    set { this.Item = (T)value; } 
} 

[XmlIgnore] 
public T Item 
//...