Since C#'s Task is a class, you obviously can't cast a Task<TDerived>
to a Task<TBase>
.
However, you can do:
public async Task<TBase> Run() { return await MethodThatReturnsDerivedTask(); }
Is there a static task method I can call to get a Task<TDerived>
instance which essentially just points to the underlying task and casts the result? I'd like something like:
public Task<TBase> Run() { return Task.FromDerived(MethodThatReturnsDerivedTask()); }
Does such a method exist? Is there any overhead to using an async method solely for this purpose?
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; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With