Pass Type parameter to generic method in runtime

3

I have a method that I use to deserialize data:

public static class CustomJson<T> where T: class, new()
{
    public static T Deserialize(string data)
    {
        try
        {
            return string.IsNullOrEmpty(data) 
                      ? default(T) 
                      : Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data);
        }
        catch (Exception ex)
        {
            throw new Exceptions.SerializationException(SerializationType.Json, ex);
        }
    }
}

The type to be used in deserialization I know only in runtime:

public void TesteCustomJson(string package, string methodName)
{
    try
    {
        var serviceFactory = new ServiceFactory();
        var service = serviceFactory.GetService<ITesteService>();

        var method = service.GetType().GetMethod(methodName);
        if (method != null)
        {
            var parameter = method.GetParameters().FirstOrDefault();
            if (parameter != null)
            {
                var parameterType = parameter.ParameterType;
                var result = Framework.Utils.Serialization.CustomJson<parameterType>.Deserialize(package);
            }
        }
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
    }
}

Doing this way does not compile, the following error is generated:

  

The type or namespace name 'parameterType' could not be found (are you missing a directive or an assembly reference?)

Is there any way to pass the type to be deserialized by knowing it only at runtime?

    
asked by anonymous 19.02.2015 / 11:23

1 answer

4

You can use the following code to pass a generic type during runtime :

public static class CustomJson<T> where T : class, new()
{
    public static T Deserialize(string data)
    {
        try
        {
            if (string.IsNullOrEmpty(data)) 
                return new T();
            return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(data);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            throw;
        }
    }
}

public class TestClass
{
    public int Id { get; set; }

    public TestClass()
    {
    }
}

public void TestGeneric()
{
    Type custom = typeof(CustomJson<>);
    Type newInstance = custom .MakeGenericType(typeof(TestClass));
    MethodInfo mi = newInstance.GetMethod("Deserialize");
    var res = mi.Invoke(null, new object[] { "{Id: 3}" });
}

Note the method .MakeGenericType . Briefly, the method creates a new CustomJson<T> with the types provided in the method. Although only T was replaced here, it could be applied to more generic types.

Example on DotNetFiddle .

    
19.02.2015 / 11:58