2016-09-29 30 views
3

我有一段非常难看的代码,它散布在整个项目中。这段代码唯一的区别在于一行中调用了不同的方法。所谓的方法总是返回一个bool构建一个通用的c#函数,允许函数作为参数传入

我想重构这个并将其提取到它自己的方法中,并将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 async Task<bool> IsCustomerComplete(int id) 
{ 
    ...removed other code here 
    return true; 
} 

这是否有道理,我是在正确的轨道上,从例子中,我发现他们只显示Funcs<>传球在stringint,这使得事情看起来很简单。

+1

只是要清楚。 '_myRepo.IsCustomerComplete'返回什么? – Nkosi

+0

它返回一个布尔值。我想要传递给这个函数的每个方法总是返回一个布尔值 –

+0

而你想让这个方法异步执行?我问,因为你的例子不会根据当前提供的信息进行编译。 – Nkosi

回答

1

这是根据您提供的详细信息的示例。

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>

如果目标函数不需要任何参数,那么你可以做其他的答案中提到,只是提供的功能本身没有插入语。

+0

感谢你们俩@recursive你的帮助已被赞赏 –

0

我会结账Action<T>Func<T, TResult>代表。

  • 当您希望传入无效匿名方法时,使用Action<T>委托。

  • 当您需要传入具有返回类型的匿名方法时,请使用Func<TResult>委托。

MSDN有一些很好的例子:

Func Delegates MSDN

Action Delegates MSDN

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

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

3

如果我了解你的目标,你就非常接近。你最缺少的是将你的方法转换为Func<>委托。在你的问题中,你包含了参数括号。如果您不调用该方法,则不需要这些。

所以,基本上,这是你可能想要的。

var process = await RepeatableMasterPiece(1, 2, _myRepo.IsCustomerComplete); 
+0

这不会编译。 OP期望'功能>'。我仍然试图澄清从OP – Nkosi

+0

预期的行为,我假设'异步'。如果它是这样定义的,它将起作用。 '公共异步任务 IsCustomerComplete()=>等待Task.FromResult(false);' – recursive

+0

我也认为同样的事情,但操作回应说'布尔IsCustomerComplete()' – Nkosi

相关问题