Dave New
Dave New

Reputation: 40002

Deserialising using a string representation of the target type

I want to deserialize to a type, but I only have the string representation of that type.

All I know is that the type implements ISomething.

string typeName = "MyClass";

BinaryFormatter binaryFormatter = new BinaryFormatter();
byte[] data = Convert.FromBase64String(serialisedString);

using (MemoryStream memoryStream = new MemoryStream(data, 0, data.Length))
{
    return (ISomething)binaryFormatter.Deserialize(memoryStream) as ISomething;
}

But I get the following exception on BinaryFormatter.Deserialize:

Unable to cast object of type 'System.RuntimeType' to type 'MyAssembly.ISomething'

How do I cast to the class name stored in typeName?

Upvotes: 1

Views: 144

Answers (2)

George Mavritsakis
George Mavritsakis

Reputation: 7083

I think the most important is WHAT you want to do with the result?

I mean, even with Sam's code you will get the result into a variable that will be of type object. You cannot use var for this. So with plain deserialize or Sam's one you will get the same result.

My question again is what you want to do with the result?

You would like to call some common methods? Is ISomething a common interface?

If that is the case and you know it beforehand then make all your types inherit from something like ISomething and then cast them to it. If not, i cannot immagine what you would do with tre result.

The one and only usage (without common interface) I could think of would be to use case for each type and do different thinks for each specific case ??? But in that ...case... you would know the type of the serialized object.

Upvotes: 0

Sam Leach
Sam Leach

Reputation: 12956

You can use:

Type type = Type.GetType(typeName);

The assembly-qualified name of the type to get. See AssemblyQualifiedName. If the type is in the currently executing assembly or in Mscorlib.dll, it is sufficient to supply the type name qualified by its namespace.

Type.GetType()

You can create a generic Deserialise method that leverages XmlSerialiser:

public class XmlDeserialiser
{
    public T Deserialise<T>(string xml) where T : class
    {
        T foo;
        try
        {
            var serializer = new XmlSerializer(typeof(T));
            foo = (T)serializer.Deserialize(new XmlTextReader(new System.IO.StringReader(xml)));
        }
        catch(Exception ex)
        {
            Console.WriteLine("Failed to Deserialise " + xml + " " + ex);
            throw;
        }

        return foo;
    }
}

Call using reflection:

MethodInfo method = typeof(XmlDeserialiser).GetMethod("Deserialise"); // XmlDeserialiser is the class which contains your Deserialise method.
MethodInfo generic = method.MakeGenericMethod(type);
generic.Invoke(this, null);

Upvotes: 3

Related Questions