构建允许将函数作为参数传入的通用 c# 函数
Building a generic c# function that allows a function to be passed in as a parameter
我有一段非常难看的代码散布在整个项目中。这段代码的唯一区别是调用不同方法的一行。调用的方法总是 returns a 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 async Task<bool> IsCustomerComplete(int id)
{
...removed other code here
return true;
}
这有意义吗,我在正确的轨道上吗,从我发现的例子中他们只显示 Funcs<>
传递 string
或 int
这让事情看起来简单多了。
我会检查 Action<T>
和 Func<T, TResult>
代表。
当您希望传入无效的匿名方法时,请使用 Action<T>
委托。
当您需要传入具有 return 类型的匿名方法时,请使用 Func<TResult>
委托。
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;
}
这里假设所有目标方法都将返回 Task<bool>
如果目标函数不需要任何参数,那么您可以按照其他答案中的说明进行操作,只需提供不带括号的函数本身。
我有一段非常难看的代码散布在整个项目中。这段代码的唯一区别是调用不同方法的一行。调用的方法总是 returns a 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 async Task<bool> IsCustomerComplete(int id)
{
...removed other code here
return true;
}
这有意义吗,我在正确的轨道上吗,从我发现的例子中他们只显示 Funcs<>
传递 string
或 int
这让事情看起来简单多了。
我会检查 Action<T>
和 Func<T, TResult>
代表。
当您希望传入无效的匿名方法时,请使用
Action<T>
委托。当您需要传入具有 return 类型的匿名方法时,请使用
Func<TResult>
委托。
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;
}
这里假设所有目标方法都将返回 Task<bool>
如果目标函数不需要任何参数,那么您可以按照其他答案中的说明进行操作,只需提供不带括号的函数本身。