Task with result unknown type

家住魔仙堡 提交于 2019-12-24 04:13:04

问题


I'm working on a async CQS API

The WebAPi method looks like this

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>

How can I return a task from result without knowing the type?

This is the code that invokes the Generic typed 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);
}

edit: Is there any reason why WebApi does not support Task<T> exposed as Task? If I change from Task to just plain Task it does not work. Its still a Task underneath so WebApi should be able to resolve that with some magic? I want todo this

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

回答1:


The question is a little confusing. It's particularly not clear where the error message is coming from. Based on the little code you posted, the only thing I see that would make sense is that you're actually getting that error message at the return statement of your Invoke() method. I.e. that handler.Handle(query as dynamic) returns an object of type Task<System.Collections.Generic.IEnumerable<Customer>>. This, of course, would not be the same as Task<object> and so would be illegal.

If I understand correctly, then it seems to me you could address the issue by changing your Invoke() method itself to be async, so that you can rewrap the eventually-returned System.Collections.Generic.IEnumerable<Customer> object in the Result of a Task<object> instead of the Task<System.Collections.Generic.IEnumerable<Customer>> that is currently being generated:

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


If that does not address your specific concern, please edit the question so that it is more clear. Please provide a good, minimal, complete code example that reliably reproduces the problem.




回答2:


Your problem here is that Task<T> is not covariant, i.e. you can't implicitly convert a Task<Something> to a Task<object> - unlike, for instance, the conversion from an IEnumerable<Something> to an IEnumerable<object>.

The easiest way to fix this is to change your Get method to await the task and return the value in two separate statements, like this:

object obj = await ...;
return obj;


来源:https://stackoverflow.com/questions/29766333/task-with-result-unknown-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!