我有一個重復呼叫另一個函式的函式。
第二個函式有一個 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
}
代碼本身顯然是一個例子(實際上第二個函式被呼叫了 20 多次,為了代碼可讀性,我希望不必每次都指定第二個引數),但我把它放在那里是為了解釋我目前在做什么. 沒有更好的方法來實作這一目標嗎?
uj5u.com熱心網友回復:
您可以引入一個本地函式來捕獲第二個引數,如下所示:
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;
}
這稱為“部分函式應用”。在這里查看更多:
https://codeblog.jonskeet.uk/2012/01/30/currying-vs-partial-function-application/
uj5u.com熱心網友回復:
雖然 C# 不支持真正的函式 Currying也不支持一流的部分函式應用程式,但您始終可以使用新的本地范圍函式(又名本地函式)來包裝您Function2的預定義引數......這在概念上幾乎與 partial 相同應用程式,只是沒有參考透明性和笨拙的委托型別。
無論如何,如果你想將 externalFunction1的differentBehavior引數值傳遞給Function2then 你將需要使用一個閉包,它會捕獲變數,但這會 帶來輕微的運行時性能問題:因為閉包通常意味著 GC 堆分配和復制功能從堆疊到堆和yada yada的本地狀態。
但是,如果您只使用常量引數值 - 或者您可以對不同的預定義引數值使用不同的包裝器,那么您可以使用static本地函式(需要 C# 8.0 或更高版本)來防止您無意中創建閉包。
例如:
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
}
uj5u.com熱心網友回復:
當在堆疊上傳遞大量引數時,需要注意的一件事是,是否存在可以由類的成員變數表示的更高級別的狀態。
這是最基本的狀態機的一些代碼。這種通用方法可能有助于解決您遇到的問題:
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();
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/481112.html
