Приведение функции как переменной

#c# #.net

#c# #.net

Вопрос:

Пусть будет следующая функция Measure для измерения времени выполнения для некоторой функции method

 public static TimeSpan Measure(Action method)
{
    var stopwatch = new Stopwatch();
    stopwatch.Start();
    method.Invoke();
    stopwatch.Stop();
    return stopwatch.Elapsed;
}
  

Этот метод запускается следующей строкой кода

 var ExecTime = ComplexityCounters.Measure(() => method(int a, int b));
  

Как мы можем видеть, это очень большой отзыв Measure , поэтому давайте попробуем сократить его с помощью следующей функции

 public static TimeSpan ExecTime (Action method)
{
   var ExecutionTime = Measure(() => method.Invoke());
   return ExecutionTime;
}
  

Но

 var ExecTime = ExecTime(method(int a, int b));
  

выдает ошибку c # не удается преобразовать из ‘void’ в ‘System.Действие’. Как это исправить? Или, может быть, есть способ объединить эти две функции в одну?

Комментарии:

1. Обратите внимание, что тип параметра ExecTime и тип параметра Measure ExecTime(() => method(a, b)) абсолютно одинаковы, поэтому их нужно вызывать одинаковым образом, например, в c #. И что ваша «рабочая» строка кода не

2. Что вы подразумеваете под «очень большим отзывом»? () => method.Invoke() это просто () => method() ненужный перенос, который должен закрываться для method параметра. Я думаю, вы пытаетесь решить проблему, которой не существует, и создаете ненужные уровни косвенности в процессе.

3. сделал это таким образом public static TimeSpan ExecTime (Action method) { Action a = () => method(); var ExecutionTime = Measure(a); return ExecutionTime; } , так что теперь это работает как var ExecutionTime = ExecTime(() => method);

4. Чрезмерно спроектировано. Каждый раз создает два экземпляра делегата вместо одного и выполняет то же самое. То, как вы начали свой вопрос, было просто замечательно.

5. @madreflection вы правы, это ненужный уровень

Ответ №1:

вот полный пример

 public static TimeSpan Measure(Action method)
    {
        var stopwatch = new Stopwatch();
        stopwatch.Start();
        method.Invoke();
        stopwatch.Stop();
        return stopwatch.Elapsed;
    }

    public static TimeSpan ExecTime(Action method)
    {
        var ExecutionTime = Measure(() => method.Invoke());
        return ExecutionTime;
    }

    private static void Main(string[] args)
    {
        var spentTime = ExecTime(() => Sum(1,2));
    }

    public static int Sum(int t1, int t2)
    {
        return t1   t2;
    }
  

на самом деле вы объявляете свою переменную ExecTime так же, как и имя вашего метода ExecTime

Комментарии:

1. также вы не передаете действие ExecTime в соответствии с вашим примером.