Search code examples
c#genericssystem.reflection

C# .Net Generic Base Class Method to return Object of that type from a json string


So, I am really not familiar with generics all that much or reflection but i was wondering if this is possible.

What I would like to do is have the FromString return the object that is created in the correct type from the json deserialization.

This line below

return JsonConvert.DeserializeObject(str);

I like to change to user the generic

return JsonConvert.DeserializeObject< my object type >(str);

public class BaseModel
{
    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
    public object FromString(string str)
    {
        return JsonConvert.DeserializeObject(str);
    }
}

Then whenever I like to serialize or deserialize the object I can use those base methods.

I know I can do a GetType(this) which will give me the assembly, the name of the object as well as the namespace.

But I am at a lost as to where to go from there.

Any help is greatly appreciated :)

Angela


Solution

  • If you want to use generics, it is easy like so:

    public class BaseModel<T>
    {
        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    
        public T FromString<T>(string str)
        {
            return JsonConvert.DeserializeObject<T>(str);
        }
    }
    

    You could also use a bit of reflection magic to have a non generic class:

    public class BaseModel
    {
        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    
        public BaseModel FromString(string str)
        {
            var type = this.GetType();
            var method = typeof(JsonConvert)
               .GetMethods()
            .FirstOrDefault(x => 
              x.Name == "DeserializeObject" 
              && x.IsGenericMethod 
              && x.GetParameters().Count() == 1).MakeGenericMethod(type);
            method.Invoke(null, new object[] { str });
            return JsonConvert.DeserializeObject<T>(str);
        }
    }
    

    Then in the second case you can just cast the result to specific model e.g.

    var mymodel = new SpecificModel();
    var result = (SpecificModel)mymodel.FromString(str);