Вы можете применять аргументы, когда вы создаете лямбду, которая будет синхронизироваться, а не внутри метода, который выполняет синхронизацию.
Таким образом, вы можете реализовать функцию хронирования следующим образом (используя кортеж для возврата двух значений):
public static (TimeSpan duration, T result) TimeFunction<T>(Func<T> func)
{
var sw = Stopwatch.StartNew();
var result = func();
return (sw.Elapsed, result);
}
Это можно использовать для определения времени функции с несколькими параметрами, например:
using System;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApp1
{
class Program
{
public static void Main()
{
// Note how we apply the parameters here, even though the
// function is actually called inside TimeFunction().
var result = TimeFunction(() => functionToTime(1, 2.0, "3"));
Console.WriteLine("Result = " + result.value);
Console.WriteLine("Duration = " + result.duration);
}
static string functionToTime(int intVal, double doubleVal, string stringVal)
{
Thread.Sleep(250);
return $"intVal = {intVal}, doubleVal = {doubleVal}, stringVal = {stringVal}";
}
public static (TimeSpan duration, T value) TimeFunction<T>(Func<T> func)
{
var sw = Stopwatch.StartNew();
var result = func();
return (sw.Elapsed, result);
}
}
}
Этот подход аналогичен «частичному применению функции», , как обсуждалось вэта статья .
Примечание. Если вы не можете использовать кортежи, потому что используете старую версию C #, вам придется объявить метод синхронизации следующим образом:
public static T TimeFunction<T>(Func<T> func, out TimeSpan duration)
{
var sw = Stopwatch.StartNew();
var result = func();
duration = sw.Elapsed;
return result;
}
и соответственно измените звонки на него.