I have an interface that requires me to return Task<T>
, but there is nothing awaitable called, hence it I could return Task.FromResult(instanceofT)
, like in following simple situation:
public Task<bool> Get()
{
return Task.FromResult(true);
}
But I have TypedResults as return type. And I get cast compiler errors:
public Task<Results<Ok, NotFound>> ReceiveCommand(ICommand command)
{
....
if (condition) return Task.FromResult(TypedResults.NotFound());
return Task.FromResult(TypedResults.Ok());
}
The only way I could get this done is by forcefully awaiting something:
public async Task<Results<Ok, NotFound>> ReceiveCommand(ICommand command)
{
....
if(condition) return await Task.FromResult(TypedResults.NotFound());
return await Task.FromResult(TypedResults.Ok());
}
or
public async Task<Results<Ok, NotFound>> ReceiveCommand(ICommand command)
{
...
await Task.CompletedTask;
if(condition) return TypedResults.NotFound();
return TypedResults.Ok();
}
It will most likely be optimized away, but I still find it ugly. I should most likely use an explicit type parameter for the generic FromResult
, but I have no clue what to use, except Results<Ok, NotFound>
which is again ugly. I find it weird that the implicit casting works for the async version but not here. What am I missing?
Task<Derived>
isn't implicitly convertible to Task<Base>
. That's called covariance. The fact that you posted an answer that makes no attempt to answer the question doesn't make the question any less of a duplicate. – AlbertoResult<T1, T2>
is not derived fromNotFound
andOk
classes, it is implicitly convertible. – JokjakartaTask
covariant. And it's failing. That it wouldn't work even if the type supported the limited covariance interfaces support doesn't change the fact that it can't be used covariant at all, and that's what they're trying to do. – AlbertoTask<IResult>
then I would completely agree with your suggested duplicate. But in this case covariance is not related. Even if return type would be someITask<out T>
the code would not work sinceResult<T, T1>
,Ok
andNotFound
do not share inheritance hierarchy (though they all implementIResult
). – JokjakartaTask
Covariantly. That there is an additional reason why it wouldn't here, beyond just the fact thatTask
doesn't support covariance at all, doesn't change that. Note that, in principle, covariance, as a concept, can be made to apply to any implicit conversion, not merely identity-preserving ones. The existing covariance of interfaces only supports identity-preserving covariant conversions, but they didn't have to do that. They could support non-identity preserving covariant conversions next version if they wanted to. – AlbertoTask
and wondering why they couldn't use it covariantly withResult
, all of your points would be valid, because the question I brought up is about the fact that no covariance is supported, not that only certain types are supported by interfaces. If they had asked that hypothetical different question it would still be a duplicate, just of a different question. – AlbertoTask
can't be used covariantly. The answer is that task doesn't support any covariance at all. That other places that do support some covariance don't support this kind of covariance is perhaps interesting, but not the answer to the question. The answer to the question is that task doesn't support any covariance. – AlbertoTask
is not covariant" being duplicate implies that ifTask
was covariant the code above would work. But it still would not. So I hope you can see why I don't agree that "becauseTask
is not covariant" is a duplicate here. Thank you for discussion - it was interesting for me and I glad that you have spent time to explain your point of view! – JokjakartaTask
not be used covariantly. The answer is it supports no covariance at all. That is the answer. If the question was asking about an interface, then there would be different duplicate relating to non-identity preserving implicit conversions. But that wasn't the question. ThatTask
supports no covariance at all doesn't logically imply that if it supported the same covariance interfaces currently do this would work. You've explained why your inferences from the answer are false, not why the answer is false. – Albertoasync
version but not here. What am I missing?" - TBH does not sound like "becauseTask
is not covariant" is the answer which fully explains the situation here. Again - thank you for discussion and excuse me if any of what I have written seemed harsh/inappropriate, had no such intentions. If you'll find the duplicate for reference preserving conversions for covariance I think we can close the question providing those too. – JokjakartaTask
, which isn't allowed, and another didn't. It turns out the answer was not in fact that they should have changed the return type of the method and not implement the interface that they claimed they were trying to implement. Even though that sounds like it would be the answer to the question, it turns out that isn't. – Alberto