构建允许函数作为参数传入的通用c#函数

构建允许函数作为参数传入的通用c#函数,c#,func,C#,Func,我有一段非常难看的代码,分散在整个项目中。这段代码的唯一区别是在一行中调用了不同的方法。调用的方法总是返回一个bool 我想重构它并将其提取到它自己的方法中,并将1行程序传递到这个方法中(如果可能的话),据我所知,我可以使用Func来实现这一点 这就是我要做的。我尽量把事情弄清楚 public async Task<bool> SomeMethod() { //code removed for readability. //IsCustomerComplete wi

我有一段非常难看的代码,分散在整个项目中。这段代码的唯一区别是在一行中调用了不同的方法。调用的方法总是返回一个
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;
            }
        }
    }
}
public异步任务SomeMethod()
{
//为了可读性删除了代码。
//IsCustomerComplete将返回bool
var流程=等待可重复的杰作(1,2,_myRepo.IsCustomerComplete(某些参数需要));
//用过程结果做某事
返回过程;
}
专用异步任务RepeatableMasterives(int-param1、int-param2、Func方法)
{
int重试=0;
bool-soapComplete=false;
string soapFault=“例如,只是一个占位符”;
bool blackListStatus=false;
而(!soapComplete&&重试1)
{
掷骰子;
}
}
}
}
回购协议

public async Task<bool> IsCustomerComplete(int id)
{
    ...removed other code here
    return true;
}
public异步任务IsCustomerComplete(int-id)
{
…删除了此处的其他代码
返回true;
}

从我发现的示例中,它们只显示
Funcs
传递
string
int
,这使事情看起来更简单。

我会签出
Action
Func
委托

  • 当您希望传入void匿名方法时,请使用
    操作
    委托

  • 当需要传入带有返回类型的匿名方法时,请使用
    Func
    委托

MSDN有一些很好的例子:

在我的职业生涯中,我多次使用动作和功能。当向无法重构的紧密耦合代码中添加特性时,它们会派上用场


但是,在编写松散耦合的代码时,应该使用它们的正确用法。很多时候,我想让实现者选择提供自己的功能

如果我理解你的目标,你就很接近了。您缺少的最大一件事是将方法转换为
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;
}
public异步任务SomeMethod(){
//方法中的代码。
var_myRepo=新回购();
var someParameterRequired=1;
var进程=等待可重复的杰作(1,2,()=>_myRepo.IsCustomerComplete(某些参数需要));
//用过程结果做某事
}
专用异步任务RepeatableMasterives(int-param1、int-param2、Func方法){
int重试=0;
bool-soapComplete=false;
string soapFault=“例如,只是一个占位符”;
bool blackListStatus=false;
而(!soapComplete&&重试1){
掷骰子;
}
}
}
返回false;
}
这里的假设是所有目标方法都将返回
Task


如果目标函数不需要任何参数,那么您可以按照其他答案中提到的操作,只提供函数本身而不带括号

我只是想说清楚。
\u myRepo.IsCustomerComplete
返回什么?它返回布尔值。我想传递给这个函数的每个方法都会返回一个boolAnd,你想异步执行这个方法吗?我这样问是因为你的例子不会根据当前提供的信息编译。这也不会编译。OP需要
Func
。我仍在试图澄清OPI的预期行为,我假设
async
。如果它是这样定义的,它将工作<代码>公共异步任务IsCustomerComplete()=>等待任务.FromResult(false)我也有同样的想法,但Op回答说
bool IsCustomerComplete()
我也看到了,并假设这是一个异步方法的简写,它正在做最合理的事情。但我可能错了。我明白你的意思。多亏了你们两个,我非常感谢你们的帮助