c# - 在 C# 中使用 MakeGenericMethod 后如何创建具体类型?
问题描述
一些背景知识,我正在使用其他人编写的一些代码。这是一个 REST API,您可以向其发出查询和命令,并以通用方式处理它们。
解析查询的方法是这样的:
[HttpPost]
[Route("query")]
public async Task<Task> ResolveQuery(ApiQuery message)
{
var type = Type.GetType(message.QueryType, true);
var query = this.serializer.Deserialize(message.Payload, type);
var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).FirstOrDefault();
var responseType = interfaceType.GetGenericArguments()[0];
var handleMethod = typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
var task = handleMethod.Invoke(this.bus, new object[] { query }) as Task;
await task;
return task;
}
我很确定以这种方式使用任务是非常不寻常的。
因此,当调用 handleMethod 时,即使它的结果被强制转换为任务,并且当我在调试期间将鼠标悬停在它上面时我可以看到有效结果,但没有任何task.Result
成员可供我用于最终强制转换。
我尝试过的事情:
我已经尝试将这个handleMethod.Invoke 转换为我需要的'resopnseType',Convert.ChangeType(result, responseType);
但我得到了一个没有实现IConvertible 的异常。我真的必须为我需要返回的每种类型实现 IConvertible 吗?
我也尝试将返回类型设置为 Task,但是我需要在 ResolveQuery 中指定 TResponse,这会导致内部服务器错误(我不确定如何从调用代码中指定 TResponse)。
我也试过问程序员他在这里做什么。他不知道。他正在遵循另一个程序员对这个实现的原始建议,但那个程序员目前不在,否则我会问他的!
谁能告诉我如何正确地从任务对象中获取我的结果并以 RESTful 方式将其返回给调用客户端?
更新- 回应@Yeldar Kurmangaliyev
public interface IQueryBus
{
Task<TResponse> ResolveAsync<TResponse>(IQuery<TResponse> query);
}
解决方案
几周前我遇到了同样的问题。不幸的是,我找不到我读到那个神圣句子的页面,但它是:
“通过反射等待泛型方法只能通过dynamic
在任务<目标类型>中解析的强制转换”
因此,举一个例子,它在您的情况下应该如何看待:
dynamic taskResult = await (dynamic)handleMethod.Invoke(this.bus, new object[] { query });
是的,动态不是最好的,但在编译器不知道泛型 T 参数是什么类型的情况下会有所帮助。
推荐阅读
- angular - 在平面图图像上没有使用 amcharts 绘制热图的解决方案
- python - 调用自定义视觉 API 时出现 KeyError:Python 中的“端点”错误
- java - 在 Java 中 - 我如何获得完整的堆栈跟踪
- python - 气流 - 巴赫命令失败
- vue.js - 如何为 vue 创建 .po 文件?
- css - 如何强制水平空间(响应式)
- antlr4 - 我可以一次解析 antlr4 输入一个前缀吗?
- python - python - 如何在plotly python中将两个图表并排放置?
- kubernetes - 有没有办法获取 Kubernetes 集群的 UID?
- python-3.x - 使用 torch.load() 时我的检查点文件有问题