构建一个通用的c#函数,允许将函数作为参数传入
本文关键字:函数 参数 一个 构建 | 更新日期: 2023-09-27 18:09:30
我有一段非常难看的代码,它分散在整个项目中。这段代码的唯一不同之处在于其中一行调用了不同的方法。被调用的方法总是返回一个bool
。
我想重构它并将其提取到自己的方法中,并将1内线传递到该方法中(如果可能的话),根据我的理解,我可以使用Func<>
来做到这一点。
这就是我要做的。我已经尽量把事情说清楚了
public async Task<bool> SomeMethod()
{
//code removed for readability.
//IsCustomerComplete will return a bool
var process = await RepeatableMasterPiece(1, 2, _myRepo.IsCustomerComplete(someParameterRequired));
//do something with process result
return process;
}
private async Task<bool> RepeatableMasterPiece(int param1, int param2, Func<Task<bool>> method)
{
int retry = 0;
bool soapComplete = false;
string soapFault = "just a placeholder for example";
bool blackListStatus = false;
while (!soapComplete && retry <= 1)
{
try
{
if (soapFault != null)
{
//do some stuff with param1 & param2 here
}
if (!soapComplete)
{
return await method.Invoke();
}
}
catch (FaultException ex)
{
soapFault = ex.Message;
retry++;
if (retry > 1)
{
throw ex;
}
}
}
}
From repo
public async Task<bool> IsCustomerComplete(int id)
{
...removed other code here
return true;
}
这有意义吗?我在正确的轨道上,从我发现的例子中,他们只显示Funcs<>
通过string
或int
,这使得事情看起来简单得多。
如果我理解你的目标,你就很接近了。你错过的最大的事情是将你的方法转换为Func<>
委托。在你的问题中,你包含了参数括号。如果您不调用该方法,则不需要这些。
所以,基本上,这就是你可能想要的。
var process = await RepeatableMasterPiece(1, 2, _myRepo.IsCustomerComplete);
下面是一个基于您提供的详细信息的示例。
public async Task SomeMethod() {
//code in method.
var _myRepo = new repo();
var someParameterRequired = 1;
var process = await RepeatableMasterPiece(1, 2, () => _myRepo.IsCustomerComplete(someParameterRequired));
//do something with process result
}
private async Task<bool> RepeatableMasterPiece(int param1, int param2, Func<Task<bool>> method) {
int retry = 0;
bool soapComplete = false;
string soapFault = "just a placeholder for example";
bool blackListStatus = false;
while (!soapComplete && retry <= 1) {
try {
if (soapFault != null) {
//do some stuff with param1 & param2 here
}
if (!soapComplete && method != null) {
return await method();
}
} catch (FaultException ex) {
soapFault = ex.Message;
retry++;
if (retry > 1) {
throw ex;
}
}
}
return false;
}
这里的假设是所有的目标方法都将返回Task<bool>
如果目标函数不需要任何参数,那么你可以按照其他答案中提到的那样做,只提供函数本身而不带括号。
我会签出Action<T>
和Func<T, TResult>
委托。
-
当你想传递一个void匿名方法时,使用
Action<T>
委托。 -
当你需要传递一个带有返回类型的匿名方法时,使用
Func<TResult>
委托。
MSDN有一些很好的例子:
Func委派MSDN
动作委托MSDN
在我的职业生涯中,我多次使用过actions和function。当向不能重构的紧密耦合代码中添加特性时,它们会派上用场。
但是,在编写松散耦合的代码时应该使用它们的正确用法。很多时候,我想给实现者提供提供自己功能的选择。