任务结果类型未知

3
我是一名有用的助手,可以为您提供文本翻译服务。
我正在处理一个异步CQS API。WebAPI方法如下所示:
public async Task<object> Get([FromUri] Contract contract)
{
    return  await _invoker.Invoke(CreateDto<Query>(contract));
}

无法隐式转换类型 'System.Threading.Tasks.Task<System.Collections.Generic.IEnumerable<Customer>>' 到 'System.Threading.Tasks.Task<object>

如果不知道类型,如何返回结果的任务?

这是调用泛型类型类的代码

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));
}

目前它返回一个Task<object>,这也需要进行更新,请参考调用者代码的更新。 - undefined
有没有任何原因声明返回 Task<object> 而不是普通的 Task - undefined
你不能有返回值吗?当以这种方式进行时,WebApi不会显示任何内容。 - undefined
错误消息提示_invoker.Invoke返回Task<IEnumerable<Customer>>,但您的Invoke代码返回Task<object>。这个类型是从哪里来的?在等待任务完成后,您应该能够将结果向上转换为object - undefined
你能不能将返回值转换为对象?对不起,我无法在控制台中轻松复制。 - undefined
2个回答

2
你的问题在于Task<T>不是协变的,也就是说,你不能隐式地将Task<Something>转换为Task<object>——与例如从IEnumerable<Something>IEnumerable<object>的转换不同。
最简单的解决方法是将你的Get方法更改为在两个独立语句中await该任务并返回该值,如下所示:
object obj = await ...;
return obj;

1
这个问题有点令人困惑。特别是不清楚错误信息来自哪里。根据你发布的少量代码,我唯一能看出来的是你实际上在Invoke()方法的return语句处得到了那个错误消息。也就是说,handler.Handle(query as dynamic)返回一个类型为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);
}

如果这不能解决你的具体问题,请编辑问题以使其更加清晰。请提供一个好的、最小的、完整的代码示例,可靠地重现问题。

这个方法是可行的,实际上和Solal Pirellis的答案是一样的。将其包装起来会有什么影响?它会导致同步任务只是将旧结果转换为对象吗?WebAPI为什么不能处理实际上是Task<T>的非泛型任务? - undefined
我会将这个标记为答案,但我的实际问题是是否可以使 WebApi 使用以 Task<T> 形式公开的 Task 工作,新问题在这里 http://stackoverflow.com/questions/29769261/return-taskt-as-plain-task-breaks-webapi - undefined
"像这样包装的影响是什么?" -- 我会说是"最小的"。操作仍然是异步的,只是继续操作在调用堆栈中的下一级实现。你最终会得到一个中间的Task对象,但我认为这是不可避免的,特别是因为问题所在:你需要(显然)从预定义的API返回一个异步的object,但你的底层API返回一个具体类型。在某个时候,具体类型必须被解包并重新包装成适当的Task<object>类型。额外的对象开销很小。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接