Question

I have a Json deserialiser class that is created using a generic parameter like this:

Deserializer<T> results = Deserializer<T>.FromFile(file);

Where T is the interface that an arbitrary number of types implement.

I'd like T to be chosen by the name of the class in the form of a string such as "Person" and the class Person implements T.

So it could be written like this:

Deserializer<Type.GetType("Person")> results = Deserializer<Type.GetType("Person")>.FromFile(file);

I have tried exactly this above and it gives me an error:

Using the generic type 'Deserializer<T>' requires 1 type arguments

I've also looked at this

http://social.msdn.microsoft.com/Forums/en-US/80690cd9-d1f2-4888-9c95-62305de9ced4/using-typegettype-with-generics

but trying to use some of these resulted in other errors such as:

randomVariable is a 'field' but is used like a 'type'

Is there a mistake in my code or am I going about this the wrong way?

How can I get this to work?

Solution My final code was

        Type genericType = typeof(Deserializer<>);
        Type[] typeArgs = {Type.GetType("Person")};
        Type deserialiserType = genericType.MakeGenericType(typeArgs);
        object repository = Activator.CreateInstance(deserialiserType);

        MethodInfo genericMethod = deserialiserType.GetMethod("FromFile");
        genericMethod.Invoke(repository, new[] {file});

Thank you all for your help

Was it helpful?

Solution

Using the answer in ModiX's link applied to your code, should result in something like this:

Type genericType = typeof(Deserializer<>);
Type[] typeArgs = { Type.GetType("Person") };
Type deserializerType = genericType.MakeGenericType(typeArgs);

object deserializer = Activator.CreateInstance(deserializerType);

MethodInfo fromFileMethod = deserializerType.GetMethod("FromFile");
fromFileMethod.Invoke(deserializer, new[] { file });

The line

MethodInfo closedMethod = genericMethod.MakeGenericMethod(typeof(Something));

is used if your method is generic, in your case if it would look something like this:

Deserializer<T>.FromFile<T2>(...)

OTHER TIPS

This is the wrong approach because the generic field requires a type and not an object of the Type class.

However, there is already a solution. How do I create a generic class from a string in C#?

Generic parameters must be "real type names", because they should be resolvable at build-time.

Type.GetType is a runtime method.

You've got many choices, for example :

This will give you the ability tu use runtime types.

  • See if deserializer can "automatically" deserialize to an instance of the good type (boxed in object) and just cast it to expected type.

  • Change your implementation to call Deserializer with the good generic parameter according the data to deserialize.

I believe what your attempting to do is implement this:

public interface Dynamic <T>
{
     T GetObject(string derserialize);
}

So essentially your class would inherit Dynamic, defining your generic type at that moment. Then you would essentially implicit or explicitly implement the method GetObject. It would accept your JSON data, then you could perform your desired logic to return it as the type of your choice.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top