Does such a method exist?
No.
Is there any overhead to using an async method solely for this purpose?
Yes. But it's the easiest solution.
Note that a more generic approach is an extension method for Task
such as Then
. Stephen Toub explored this in a blog post and I've recently incorporated it into AsyncEx.
Using Then
, your code would look like:
public Task<TBase> Run()
{
return MethodThatReturnsDerivedTask().Then(x => (TBase)x);
}
Another approach with slightly less overhead would be to create your own TaskCompletionSource<TBase>
and have it completed with the derived result (using TryCompleteFromCompletedTask
in my AsyncEx library):
public Task<TBase> Run()
{
var tcs = new TaskCompletionSource<TBase>();
MethodThatReturnsDerivedTask().ContinueWith(
t => tcs.TryCompleteFromCompletedTask(t),
TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}
or (if you don't want to take a dependency on AsyncEx):
public Task<TBase> Run()
{
var tcs = new TaskCompletionSource<TBase>();
MethodThatReturnsDerivedTask().ContinueWith(t =>
{
if (t.IsFaulted)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(t.Result);
}, TaskContinuationOptions.ExecuteSynchronously);
return tcs.Task;
}