How to write a method that can handle Task and ValueTask?
c#, c#-7.0
Solution
According to official documentation: Generalized async return types
The `ValueTask` struct has a constructor with a `Task` parameter so that you can construct a `ValueTask` from the return value of any existing async method:
That means you can write an overload that will wrap the `body` and call only one method that will do the work
static Task Measure<T>(Func<Task<T>> body)
{
var wrapped = () => new ValueTask<T>( body() );
return Measure( wrapped );
}
static async Task Measure<T>(Func<ValueTask<T>> body)
{
Console.WriteLine($"Starting perf test");
var sw = Stopwatch.StartNew();
await body();
sw.Stop();
Console.WriteLine(sw.Elapsed);
}
Problem
Imagine you want to write a method similar to the following one. It wraps a function returning a `ValueTask<T>` with trivial performance monitoring code: ``` static async Task Measure<T>(Func<ValueTask<T>> body) { Console.WriteLine($"Starting perf test"); var sw = Stopwatch.StartNew(); await body(); sw.Stop(); Console.WriteLine(sw.Elapsed); } ``` My question is: Is there a way to write this function once so that it can receive `Func<ValueTask<T>>` and `Func<Task<T>>`? Of course you could simply duplicate the code and change just the parameter's type. ``` static async Task Measure<T>(Func<Task<T>> body) { ... } ``` The implementation would be absolutely identical. I am asking myself if it is possible to avoid this kind of code duplication when having to deal with `ValueTask` and `Task`. Up to now, I could not come up with a good solution. Any ideas?