c# - 如何使用方法调用作为参数

标签 c# .net lambda delegates

在 C# 中,如何将一个方法作为另一个方法的参数传递,通过将参数与被调用的方法一起传递,以便在内部调用该方法,例如,测量其执行的目标?

代码能不能接近下面的伪代码?

public TR MeasureExecutionTime<T1, T2, T3, T4, T5, T6, TR>(this Func<T1, T2, T3, T4, T5, T6, TR> func, out long executionTime)
{
    Stopwatch stopwatch = Stopwatch.StartNew();

    TR tr = func();

    stopwatch.Stop();

    executionTime = stopwatch.ElapsedMilliseconds;

    return tr;
}

...

var result = MeasureExecutionTime(() => obj.Process(p1, p2, p3, p4, p5, p6), out long executionTime);

这里的主要问题似乎是如何传递和推导被调用者参数p1、p2、p3、p4、p5、p6。这怎么写得尽可能灵活和简单?

最佳答案

您可以在创建要计时的 lambda 时应用参数,而不是在执行计时的方法中应用参数。

所以你可以像这样实现计时功能(使用元组返回两个值):

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);
        }
    }
}

这种做法类似于“偏函数应用”,as discussed in this article .

注意:如果您因为使用的是旧版本的 C# 而不能使用元组,则必须像这样声明计时方法:

public static T TimeFunction<T>(Func<T> func, out TimeSpan duration)
{
    var sw = Stopwatch.StartNew();
    var result = func();
    duration = sw.Elapsed;

    return result;
}

并相应地更改对它的调用。

关于c# - 如何使用方法调用作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58340756/

相关文章:

c# - 如何将非数组 json 反序列化为实现 List<T> 的子类?

c# - 运行所有测试时测试失败,但一个一个运行成功

c# - 如何使用 WMI 或 System.Net.NetworkInformation windows 10 在 c# 中获取当前连接的 wifi SSID?

Java 8 身份映射 lambda?

javascript - 为什么箭头函数没有参数数组?

java - 如何将这 2 个 lambda 表达式合并到一个 GroupBy 调用中?

c# - 找到一组特定的局部最小值

c# - 机器人数据未保存

c# - C# 中最重要的优化性能最佳实践是什么

c# - 如何在 ASP.NET 中调试生产应用程序?