c# 如何从 Json 字符串到 class 实例然后调用方法

c# How to get from a Json string to class instance then calling method

我有一个 (sql) table,其中包含这些条目:

Table:

Type (varchar)     Json (varchar)
MyClassA           { "Id": 1, "Name": "OneName" }   
MyClassB           { "Id": 2, "Name": "TwoName" }

我需要调用 ClassA and/or ClassB 中的方法来更改名称 属性。

类似于下一个代码:

public void Test(string type, string json)
{
   Type type = Type.GetType($"MyNamespace.a.b.{type}, MyDll");

   // Some code here....
   // - Casting to IData    ??
   // - var obj = JsonConvert.DeserializeObject(json);       ??
   // - var obj = JsonConectt.DeserializeObject<type>(json)  ??
   // - var x = Convert.Change(...) ??


   instance.DoSomething("bazinga");

}


public interface IData 
{
   void DoSomething();
}

public class MyClassA : IData
{
   public int Id {get; set;}
   public string Name {get; set;}

   public void DoSomething(string newName)
   {
       Name = newName;
   }
}

public class MyClassB : IData
{
   public int Id {get; set;}
   public string Name {get; set;}

   public void DoSomething(string newName)
   {
       name = $"{Id}, {newName}";
   }
}

尝试 A:

var obj = JsonConvert.DeserializeObject(json);
var ins = obj as IData;
// ins = null

尝试 B:

dynamic obj = JsonConvert.DeserializeObject<dynamic>(json);
// failed

尝试 C:

var obj = JsonConvert.DeseriallizeObject<type>(json);
// Not allowed to use 'type' in this way.

因此,首先,您必须为通常在运行时完成的每个泛型调用创建一个专用类型。要自己创建该类型,您需要做的是使用一些反射:

public void Test(string type, string json)
{
    Type type = Type.GetType($"MyNamespace.a.b.{type}, MyDll");
    // from all method named "DeserializeObject"
    // find the one that is generic method
    MethodInfo deserializeObjectMethodInfo = typeof(JsonConvert)
        .GetMethods(BindingFlags.Static | BindingFlags.Public)
        .FirstOrDefault(m => m.IsGenericMethod && m.Name == "DeserializeObject");
    // create a specialized method for the requested type
    // same as you would call DeserializeObject<type>
    MethodInfo specializedDeserializeObject = deserializeObjectMethodInfo.MakeGenericMethod(type);
    // invoke that method with json as parameter
    // and cast it to IData
    IData data = (IData)specializedDeserializeObject.Invoke(null, json);
    // do whatever you want with the deserialized object
    data.DoSomething("bazinga");
}

您可以执行以下操作:

var instance = JsonConvert.DeserializeObject(json, type) as IData;

请参阅 HERE 获取官方文档。第二个参数将定义要反序列化的类型。