Search code examples
c#parametersfuncstopwatchmeasure

Pass a Function with multiple parameters as a Parameter


I have this piece of code, that takes a single function with no parameter, and return's its runtime.

public static Stopwatch With_StopWatch(Action action)
{
    var stopwatch = Stopwatch.StartNew();
    action();
    stopwatch.Stop();
    return stopwatch;
}

I would like to transform it to take non void functions with parameters. I heard about the Func<> delegate, but I have no idea how to use it. And I need something like this (very pseudo) :

   public T measureThis(ref Stopwatch sw, TheFunctionToMeasure(parameterA,parameterB))
   {
       sw.Start(); // start stopwatch
       T returnVal = TheFunctionToMeasure(A,B); // call the func with the parameters
       stopwatch.Stop(); // stop sw
       return returnVal; // return my func's return val
   }

So I have to get the return value of the passed func, AND get the stopwatch in the end. Any help is greatly appreciated!


Solution

  • Your original code can still work. How people will call it is what changes when you have parameters:

    With_Stopwatch(MethodWithoutParameter);
    With_Stopwatch(() => MethodWithParameters(param1, param2));
    

    you can also call the method with parameters with the second syntax:

    With_Stopwatch(() => MethodWithoutParameter());
    With_Stopwatch(() => MethodWithParameters(param1, param2));
    

    Update: if you want the return value, you can change your measureThis function to take a Func<T> instead of an Action:

    public T measureThis<T>(Stopwatch sw, Func<T> funcToMeasure)
    {
        sw.Start();
        T returnVal = funcToMeasure();
        sw.Stop();
        return returnVal;
    }
    
    Stopwatch sw = new Stopwatch();
    int result = measureThis(sw, () => FunctionWithoutParameters());
    Console.WriteLine("Elapsed: {0}, result: {1}", sw.Elapsed, result);
    double result2 = meashreThis(sw, () => FuncWithParams(11, 22));
    Console.WriteLine("Elapsed: {0}, result: {1}", sw.Elapsed, result);