Reputation: 607
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
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