Haighstrom
Haighstrom

Reputation: 607

Serialising Type-Value pairs C#

I have a class which needs a list of type-value pairs of arbitrary length.

For example one instance may hold { (string, "hello"), (int, 3) }, and another may hold { (char, 'a') }. The type will only ever be a primative type, and I could limit to only int and string, but I would rather it be possible to include float, char, etc to keep to flexible.

I need to serialize and deserialize instances of this class. My preferred serialization is XML using System.Xml.Serialization.XmlSerializer.

Tuple<Type, object> 

was no good because neither Tuple nor object serializes by default, so I defined a custom struct:

[Serializable]
public struct ObjectDataItem { public Type Type; public string Value; }

and my class holds a list of ObjectDataItems (string was fine for Value as I guess some type conversion is inevitable somewhere anyway).

My question is how I do I deserialize the ObjectDataItem (in particular deserializing the 'Type' variable)?

I am currently deserializing using the code:

    public static M LoadXML<M>(string fileName) where M : struct
    {
        if (File.Exists(fileName))
        {
            FileStream loadStream = new FileStream(fileName, FileMode.Open);
            XmlSerializer serializer = new XmlSerializer(typeof(M));
            M fileLoaded = (M)serializer.Deserialize(loadStream);
            loadStream.Close();
            return fileLoaded;
        }
        else throw new HException("File not found: {0}", fileName);
    }

Upvotes: 1

Views: 106

Answers (1)

ASpirin
ASpirin

Reputation: 3651

You can save only the type name and restore it after serializing or in the property itself

new ObjectDataItem { TypeName = typeof(int).FullName, Value = 3.ToString() }
...
public struct ObjectDataItem 
{
    public string TypeName;
    public string Value;

    [XmlIgnore]
    public Type RealType
    {
        get
        {
            return Type.GetType(TypeName);
        }
    }
}

If you will make your Value field of type object Serializer would stores the type in XML and put the correct type in the deserialization

<Value xsi:type="xsd:int">3</Value>

and your DataObjectItem will looks like

public struct ObjectDataItem
{
    public object Value;

    [XmlIgnore]
    public Type Type
    {
        get
        {
            return Value.GetType();
        }
    }
}

Upvotes: 1

Related Questions