c# - 在 C# 中使用 MakeGenericMethod 后如何制作具体类型?

标签 c# rest generics casting task

一些背景知识,我正在使用其他人编写的一些代码。这是一个 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 时,即使它的结果被转换为任务,并且在调试期间当我将鼠标悬停在它上面时我可以看到一个有效结果,但没有任务.Result 成员供我用于最终转换。

我尝试过的事情:

我已尝试使用 Convert.ChangeType(result, responseType); 将此 handleMethod.Invoke 转换为我需要的“resopnseType”,但我遇到了未实现 IConvertible 的异常。我真的必须为我需要返回的每种类型实现 IConvertible 吗?

我也试过将返回类型设置为 Task,但我需要在 ResolveQuery 中指定 TResponse,这会导致内部服务器错误(我不确定如何从调用代码中指定 TResponse)。

我也试过问程序员他在这里做什么。他不知道。他正在按照另一位程序员的原始建议进行此实现,但该程序员目前不在,否则我会问他!

谁能告诉我如何正确地从任务对象中获取结果并将其以 RESTful 方式返回给调用客户端?

更新 - 回应@Yeldar Kurmangaliyev

public interface IQueryBus
{
    Task<TResponse> ResolveAsync<TResponse>(IQuery<TResponse> query);
}

最佳答案

没有Result ,因为它只是一个非泛型 Task .
为了获得结果,您需要 Task<T> .因为你不知道 T在设计时,你需要再次使用反射:

public async Task<object> ResolveQuery(ApiQuery message)
{
    var type = Type.GetType(message.QueryType, true);

    var query = this.serializer.Deserialize(message.Payload, type);
    var interfaceType = type.GetGenericInterfaces(typeof(IQuery<>)).Single();
    var responseType = interfaceType.GetGenericArguments().Single();
    var handleMethod =     typeof(IQueryBus).GetMethod("ResolveAsync").MakeGenericMethod(responseType);
    var task = (Task)handleMethod.Invoke(this.bus, new object[] { query });
    await task;

    return typeof(Task<>).MakeGenericType(responseType).GetProperty("Result").GetValue(task);
}

它将创建一个 Result您的特定属性Task<responseType>并返回它的值。

我也稍微更新了现有代码,作为建议:

  • 已更改 [0].FirstOrDefault().Single()避免NullReferenceException , 因为预计只有一个值
  • 已替换 as Task直接投,因为预计是Task

关于c# - 在 C# 中使用 MakeGenericMethod 后如何制作具体类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53410891/

相关文章:

javascript - 在调用函数 “App.ServisTanimId.getValue”之前如何检查函数0x104567910是否作为属性存在?

typescript - 如何让 TypeScript 查找类型在这种情况下工作?

generics - 如何在 Rust 中添加一个泛型类型实现另一个泛型类型的约束?

c# - nuget 包 dll 或源文件

c# - 如何判断事件是否来自 C# 中的用户输入?

IOS 如何使用 RESTFUL API 从 Web 服务中检索数据

java - 用于编排 Web 服务的工具

RESTful 资源和正交资源问题

java - SpringBoot 使用 MongoDB 实现通用 DAO

c# - 什么是 Humble Object 模式,它何时有用?