通用属性的序列化 [英] Serialization of generic properties

查看:149
本文介绍了通用属性的序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以向我解释为什么这个第一个例子会序列化成XML,第二个例子会抛出关于试图将所有类型转换为对方的运行时错误?如果我从第二个示例中删除 XmlElement 属性,它将会序列化,但是XML元素名称将会出错(Item而不是其类型指定的名称)。第一个片段是使用模式文件从XSD工具生成的。



更好的是,有没有办法让这个工作起作用?我更喜欢使用通用类型来投射/从对象。它使得代码更简洁。显式转换对象表明您的设计存在问题。

  public partial class OAIPMHtype 
{
private object itemsField;
$ b $ [XmlElement(GetRecord,typeof(GetRecordType))]
[XmlElement(Identify,typeof(IdentifyType))]
[XmlElement(ListIdentifiers,typeof (ListIdentifiersType))]
[XmlElement(ListMetadataFormats,typeof(ListMetadataFormatsType))]
[XmlElement(ListRecords,typeof(ListRecordsType))]
[XmlElement(ListSets,类型(OAIPMHerrorType))]
公共对象Item
{
get {return this.itemsField; }
set {this.itemsField = value; }
}
}

这不会序列化。

  public class OaiPmh< T> 
{
private T itemsField;
$ b $ [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 对象时,额外的类型并没有帮助。



这是抛出的异常:

 无法生成临时类(结果= 1)。 
错误CS0030:无法将类型'ErrorRequest'转换为'GetRecordRequest'
错误CS0030:无法将类型'ErrorRequest'转换为'ListRecordsRequest'
错误CS0030:无法将类型'ErrorRequest'转换为'IdentityRequest '
错误CS0030:无法将类型'ErrorRequest'转换为'ListSetsRequest'
错误CS0030:无法将类型'ErrorRequest'转换为'ListIdentifiersRequest'
错误CS0030:无法将类型'ErrorRequest'转换为' ListMetadataFormatsRequest'
错误CS0029:不能隐式地将类型'ListSetsRequest'转换为'ErrorRequest'
错误CS0029:无法将类型'ListIdentifiersRequest'隐式转换为'ErrorRequest'
错误CS0029:无法隐式转换类型' ListMetadataFormatsRequest'到'ErrorRequest'
错误CS0029:不能隐式地将类型'GetRecordRequest'转换为'ErrorRequest'
错误CS0029:不能隐式地将类型'ListRecordsRequest'转换为'Erro rRequest'
错误CS0029:不能将类型'IdentityRequest'隐式转换为'ErrorRequest

'



这对于泛型是有意义的,看看类型是如何在编译时绑定的。但看到它如何与对象引用一起工作,在我看来,它也应该与泛型类型一起工作。

我认为 MSDN上的CS0029编译器错误页面提供您正在寻找的信息。

根据我阅读这篇文章的方式,您的第一个示例工作原理是因为您的班级中没有发生转化。因为你的显式传递了一个 Object ,所以不需要进行任何转换,也不会引发编译器错误。

在第二个示例中,类型在运行时间之前是未知的。通过指定多个XmlElement属性,编译器认为所有这些类型都必须是可互换的。但是,由于您没有为这些提供明确的转换,因此编译器担心两种类型之间的转换可能会缩小转换范围并引发错误。


Can someone explain to me why this first example will serialize into XML, and the second will throw runtime errors about trying to convert all of the types to each other? If I remove the XmlElement attributes from the second example, it will serialize but the XML element name will be wrong ( "Item" instead of the one specified for its type). The first snippet was generated from the XSD tool using the schema file.

Better yet, is there a way to get this to work? I would much prefer to use generic types that casting to/from objects. It makes for much cleaner code. Explicitly casting objects shows there's a problem in your design.

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; }
    }
}

This will not serialize.

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; }
    }
}

And for further clarification, I have tried specifying all the extra types when creating the XmlSerializer object, and that does not help.

This is the exception that's thrown:

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

'

It kind of makes sense with the generic type, seeing how the type is specific bound at compile time. But seeing how it works with an object reference, in my mind it should also work with the generic type.

解决方案

I think that the CS0029 compiler error page on MSDN provides the information you're looking for.

Based on how I read this article, your first example works because there is no conversion happening in your class. Because you explicity are passing around an Object there is no conversion that needs to happen and no compiler errors are thrown.

In the second example the type is not known until run time. By specifying multiple XmlElement attributes the compiler thinks that all of these types must be interchangeable. However, since you haven't provided explicit conversions for these the compiler is concerned that a conversion between the two types could be a narrowing conversion and throws the error.

这篇关于通用属性的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆