C#将函数作为参数传递[重复]

Posted

技术标签:

【中文标题】C#将函数作为参数传递[重复]【英文标题】:C# Passing Function as Argument [duplicate] 【发布时间】:2011-04-07 00:50:24 【问题描述】:

我用 C# 编写了一个函数来进行数值微分。它看起来像这样:

public double Diff(double x)

    double h = 0.0000001;

    return (Function(x + h) - Function(x)) / h;

我希望能够传入任何函数,例如:

public double Diff(double x, function f)

    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;

我认为委托可以做到这一点(也许?),但我不确定如何使用它们。

任何帮助将不胜感激。

【问题讨论】:

这能回答你的问题吗? Pass Method as Parameter using C# 【参考方案1】:
public static T Runner<T>(Func<T> funcToRun)

    //Do stuff before running function as normal
    return funcToRun();

用法:

var ReturnValue = Runner(() => GetUser(99));

【讨论】:

我很好奇,为什么是泛型类型参数? 我收到此错误:无法从用法中推断出方法“Runner(Func)”的类型参数。尝试明确指定类型参数。 你的“funcToRun”方法签名是什么?【参考方案2】:

使用上面提到的 Func 是可行的,但也有代理执行相同的任务并在命名中定义意图:

public delegate double MyFunction(double x);

public double Diff(double x, MyFunction f)

    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;


public double MyFunctionMethod(double x)

    // Can add more complicated logic here
    return x + 10;


public void Client()

    double result = Diff(1.234, x => x * 456.1234);
    double secondResult = Diff(2.345, MyFunctionMethod);

【讨论】:

在 3.5 及更高版本中,Funcs 和委托是可互换的,这意味着匿名委托和 lambda(它们是匿名委托的语法糖)也可以使用。因此,将参数指定为 Func 还是采用双精度并返回双精度的委托并不重要。命名委托给您的唯一真正优势是能够添加 xml-doc cmets;描述性名称与参数名称而不是类型一样易于实现。 我认为方法原型仍然使代码比 Func 更具可读性 - 不仅仅是命名使代码可读,正如你所说,这并不能阻止你将 lambdas 传递到代码中。 如果委托类型的命名对于代码的清晰度如此重要,我认为在大多数情况下我会倾向于接口和实现。 @qstarin 这不仅仅是委托的命名,而是方法必须采用的参数的命名,特别是如果它们只是本机类型。你是对的,我主要使用接口而不是委托 如果我将其中一个作为提供通用功能的通用函数,(具有不那么常见的返回类型)一切正常,直到我尝试将它与 void 一起使用。我真的需要使用 Action 而不是 Func 来创建一个重复的函数还是有更好的方法?【参考方案3】:

.Net(v2 及更高版本)中有几个泛型类型,它们使作为委托传递函数非常容易。

对于具有返回类型的函数,有 Func,对于没有返回类型的函数,有 Action。

Func 和 Action 都可以声明为采用 0 到 4 个参数。例如,Func 将一个 double 作为参数并返回一个 int。 Action 将三个 double 作为参数,不返回任何内容(void)。

所以你可以声明你的 Diff 函数来获取 Func:

public double Diff(double x, Func<double, double> f) 
    double h = 0.0000001;

    return (f(x + h) - f(x)) / h;

然后你这样称呼它,只需给它一个适合你的 Func 或 Action 签名的函数名称:

double result = Diff(myValue, Function);

您甚至可以使用 lambda 语法编写函数:

double result = Diff(myValue, d => Math.Sqrt(d * 3.14));

【讨论】:

在 .NET 4 中,FuncAction 都已更新为允许使用 up to 16 参数。 返回一个Func&lt;double, double&gt; 是很酷的事情,它是输入函数的一阶导数,当然是数值计算的。 return x =&gt; (f(x + h) - f(x)) / h; 你甚至可以编写一个重载,返回输入函数的n th 导数。

以上是关于C#将函数作为参数传递[重复]的主要内容,如果未能解决你的问题,请参考以下文章

将函数作为参数传递[重复]

在c#中将引用数组作为参数传递[重复]

将参数作为接口传递[重复]

传递方法作为参数[重复]

在函数c ++中将变量作为默认参数传递[重复]

c# 请问数组能作为参数传递吗? 如果可以如何传递呢?