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?

Original source