[英]Call function with a parameter from another function
I have a function that repeatedly calls another function.我有一个重复调用另一个函数的函数。
The second function has a bool parameter that changes the way it behaves, so when I call the first function I want to have a parameter that specifies the way the second function behaves.第二个函数有一个 bool 参数来改变它的行为方式,所以当我调用第一个函数时,我想要一个参数来指定第二个函数的行为方式。
void Function1(int n, bool differentBehavior = false)
{
int a = Function2(n, differentBehavior);
int b = Function2(1, differentBehavior);
int c = Function2(2, differentBehavior);
return a + b + c;
}
int Function2(int x, bool differentBehavior)
{
if (!differentBehavior) // do something
else // do something else
}
The code itself is obviously an example (in reality the second function is called over 20 times and for code readability I would love to not have to specify the second parameter every time), but I put it there to explain what I'm currently doing.代码本身显然是一个例子(实际上第二个函数被调用了 20 多次,为了代码可读性,我希望不必每次都指定第二个参数),但我把它放在那里是为了解释我目前在做什么. Is there no better way to achieve this?
没有更好的方法来实现这一目标吗?
You can introduce a local function to capture the second argument like so:您可以引入一个本地函数来捕获第二个参数,如下所示:
int Function1(int n, bool differentBehavior = false)
{
int func(int n) => Function2(n, differentBehavior);
int a = func(n);
int b = func(1);
int c = func(2);
return a + b + c;
}
This is called "partial function application".这称为“部分函数应用”。 See more here:
在这里查看更多:
https://codeblog.jonskeet.uk/2012/01/30/currying-vs-partial-function-application/ https://codeblog.jonskeet.uk/2012/01/30/currying-vs-partial-function-application/
While C# doesn't support true function Currying nor first-class partial function application , you can always use a new locally scoped function (aka a local function ) to wrap your Function2
with predefined arguments... which is conceptually almost the same thing as partial application, just without referential-transparency , and awkward delegate types.虽然 C# 不支持真正的函数 Currying也不支持一流的部分函数应用程序,但您始终可以使用新的本地范围函数(又名本地函数)用预定义的参数包装您的
Function2
......这在概念上几乎与部分应用,只是没有引用透明和笨拙的委托类型。
Anyway, if you want to pass the outer Function1
's differentBehavior
argument value to Function2
then you will need to use a closure, which will capture the variable, but this will introduce slight runtime performance complications : as a closure generally means a GC heap allocation and copying function local state from the stack onto the heap and yada yada.无论如何,如果您想将外部
Function1
的differentBehavior
参数值传递给Function2
,那么您将需要使用一个闭包,它将捕获变量,但这会带来轻微的运行时性能问题:因为闭包通常意味着 GC 堆分配并将函数本地状态从堆栈复制到堆和yada yada。
However, if you're only using constant parameter values - or you're okay with using different wrappers for different predefined argument values, then you can use a static
local function (requires C# 8.0 or later) which prevents you from unintentionally creating a closure.但是,如果您只使用常量参数值 - 或者您可以对不同的预定义参数值使用不同的包装器,那么您可以使用
static
本地函数(需要 C# 8.0 或更高版本)来防止您无意中创建闭包.
For example:例如:
void Function1(int n, bool differentBehavior = false)
{
// Look ma, no closure!
static int PartiallyAppliedFunc2_False(int x) => Function2( x: x, differentBehavior: false );
static int PartiallyAppliedFunc2_True(int x) => Function2( x: x, differentBehavior: true );
int a = PartiallyAppliedFunc2_False(n);
int b = PartiallyAppliedFunc2_False(1);
int c = PartiallyAppliedFunc2_True(2);
return a + b + c;
}
int Function2(int x, bool differentBehavior)
{
if (!differentBehavior) // do something
else // do something else
}
One thing to look at when a lot of parameters are being passed on the stack is whether there is some higher-level state that could be represented by a member variable of the class.当在堆栈上传递大量参数时,需要注意的一件事是,是否存在可以由类的成员变量表示的更高级别的状态。
Here's some code for the most basic kind of state machine.这是最基本的状态机的一些代码。 This general approach might help solve the problem you're having:
这种通用方法可能有助于解决您遇到的问题:
class Program
{
enum Behaviors
{
BehaviorA,
BehaviorB,
BehaviorC,
}
static Behaviors State { get; set; }
static void Main(string[] args)
{
for (State = Behaviors.BehaviorA; State <= Behaviors.BehaviorC; State++)
{
Console.WriteLine($"Function returned { Function1(0)}");
}
int Function1(int n)
{
int a = Function2(n);
int b = Function2(1);
int c = Function2(2);
return a + b + c;
}
int Function2(int x)
{
switch (State)
{
case Behaviors.BehaviorA:
return x * 10;
case Behaviors.BehaviorB:
return x * 20;
case Behaviors.BehaviorC:
return x * 30;
default:
throw new NotImplementedException();
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.