Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialization of generic properties

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.

like image 931
MonkeyWrench Avatar asked Feb 11 '11 19:02

MonkeyWrench


People also ask

What are the types of serialization?

Basic and custom serialization Binary and XML serialization can be performed in two ways, basic and custom.

What is serialization in XML?

XML serialization is the process of converting XML data from its representation in the XQuery and XPath data model, which is the hierarchical format it has in a Db2® database, to the serialized string format that it has in an application.

Can Unity serialize generics?

Unity will not serialize any generic type variant.

What is serialization in soap?

In SOAP and BINARY serialization technique the state of the entire object is serialized into a stream of bytes. In cases where the object contains a reference to other objects, even those are serialized. This type of serialization is known as deep serialization.


1 Answers

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.

like image 92
pmartin Avatar answered Sep 28 '22 04:09

pmartin