Mon*_*nch 9 .net c# xml generics xml-serialization
有人可以向我解释为什么第一个例子将序列化为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; }
}
}
Run Code Online (Sandbox Code Playgroud)
这不会序列化.
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; }
}
}
Run Code Online (Sandbox Code Playgroud)
为了进一步说明,我在创建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
Run Code Online (Sandbox Code Playgroud)
"
对泛型类型有意义,看看类型在编译时是如何特定绑定的.但是看看它如何与对象引用一起工作,在我看来它也应该与泛型类型一起使用.
我认为MSDN 上的 CS0029 编译器错误页面提供了您正在寻找的信息。
根据我阅读本文的方式,您的第一个示例有效,因为您的类中没有发生转换。因为您明确地传递了一个,Object所以不需要进行任何转换,并且不会引发编译器错误。
在第二个示例中,直到运行时才知道类型。通过指定多个 XmlElement 属性,编译器认为所有这些类型都必须是可互换的。但是,由于您没有为这些类型提供显式转换,编译器担心这两种类型之间的转换可能是缩小转换并引发错误。