结果类型未知的任务

Task with result unknown type

我正在开发异步 CQS API

WebAPI 方法如下所示

public async Task<object> Get([FromUri] Contract contract)
{
    return  await _invoker.Invoke(CreateDto<Query>(contract));
}

Cannot implicitly convert type 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<Customer>>' to 'System.Threading.Tasks.Task<object>

如何在不知道类型的情况下从结果中 return 任务?

这是调用通用类型的代码 class

public Task<object> Invoke(Query query)
{
    var queryHandlerType = typeof(IQueryHandler<,>);
    var queryType = query.GetType();
    var queryResultType = queryType.BaseType.GetGenericArguments().First();
    var handler = _container.GetInstance(queryHandlerType.MakeGenericType(queryType, queryResultType)) as dynamic;
    return handler.Handle(query as dynamic);
}

编辑: WebApi 不支持 Task<T> 暴露为任务有什么原因吗?如果我从 Task 更改为普通 Task,它就不起作用。它仍然是一个任务,所以 WebApi 应该能够用一些魔法来解决这个问题?我想这样做

public Task Get([FromUri] Contract contract)
{
    return _invoker.Invoke(CreateDto<Query>(contract));
}

问题有点乱。特别不清楚错误消息的来源。根据您发布的小代码,我认为唯一有意义的是您实际上在 Invoke() 方法的 return 语句中收到该错误消息。 IE。 handler.Handle(query as dynamic) returns 类型 Task<System.Collections.Generic.IEnumerable<Customer>> 的对象。当然,这与 Task<object> 不同,因此是非法的。

如果我理解正确,那么在我看来你可以通过将 Invoke() 方法本身更改为 async 来解决这个问题,这样你就可以重新包装最终返回的 System.Collections.Generic.IEnumerable<Customer> 对象在 Task<object>Result 中,而不是当前正在生成的 Task<System.Collections.Generic.IEnumerable<Customer>> 中:

public async Task<object> Invoke(Query query)
{
    var queryHandlerType = typeof(IQueryHandler<,>);
    var queryType = query.GetType();
    var queryResultType = queryType.BaseType.GetGenericArguments().First();
    var handler = _container.GetInstance(queryHandlerType.MakeGenericType(queryType, queryResultType)) as dynamic;
    return await handler.Handle(query as dynamic);
}


如果这不能解决您的具体问题,请编辑问题以使其更清楚。请提供能够可靠重现问题的 a good, minimal, complete code example

你的问题是 Task<T> 不是协变的,即你不能将 Task<Something> 隐式转换为 Task<object> - 例如,不同于从 IEnumerable<Something>IEnumerable<object>.

解决此问题的最简单方法是将 Get 方法更改为 await 任务和 return 两个单独语句中的值,如下所示:

object obj = await ...;
return obj;