如何为JsonSerializer.DeserializeAsync动态指定反序列化目标类型
解决方案
C#泛型参数为编译期确定,无法直接传入运行时获取的Type类型变量作为泛型参数,可通过以下两种方案实现需求:
方案一:针对Json反序列化场景(优先使用)
System.Text.Json的JsonSerializer原生提供非泛型的DeserializeAsync重载,直接传入运行时得到的Type变量即可,无需反射:
IInterface Obj; Type type; // 你的多条件判断逻辑给type赋值 if(/* 条件1 */) { type = typeof(Type1); } else { type = typeof(Type2); } // 调用非泛型重载,强转为目标接口即可 Obj = (IInterface)await JsonSerializer.DeserializeAsync(memoryStream, type, JsonOpt); return Obj;
方案二:通用动态调用泛型方法方案
针对自定义泛型方法的场景,可通过反射构造封闭泛型方法后调用,示例如下:
Test test = new(); Type t; // 你的多条件判断逻辑给t赋值 if (/* 条件1 */) { t = typeof(TimeZoneInfo); } else { t = typeof(TimeZone); } // 1. 获取泛型方法的元数据 var genericMethodDefinition = typeof(Test).GetMethod(nameof(Test.Ooo)); // 2. 绑定运行时类型,构造可执行的封闭泛型方法 var constructedMethod = genericMethodDefinition.MakeGenericMethod(t); // 3. 调用方法,返回结果为Task类型的装箱对象 var task = (Task)constructedMethod.Invoke(test, parameters: null); // 4. 等待异步任务执行完成 await task; // 5. 反射获取Task<T>的Result属性值 object result = task.GetType().GetProperty("Result").GetValue(task);
注意事项
- 反射调用性能略低于直接调用泛型方法,高频调用场景建议缓存构造完成的封闭泛型方法实例,避免每次重复反射查找
- 运行时类型转换需做好兼容性校验,可增加异常捕获逻辑避免转换错误导致程序崩溃
- 若目标泛型方法有入参,将参数按顺序组成
object[]数组传入Invoke方法的第二个参数即可
内容的提问来源于stack exchange,提问作者Švandič
相关产品推荐
相关产品推荐

