跨通用函数隔离公共代码 [英] Isolate common code across generic functions
问题描述
我在一个类中有两个函数.唯一的区别是函数的参数(一个采用带有 X 的 Func,另一个采用 Y)和标有星号的行.
I have two functions in a class. The only differences are the parameter to the function (one taking a Func with a X and the other a Y) and the lines marked with asterisks.
有什么办法可以用星号隔离这两行或者有一个共同的函数,或者重写函数,使得try、catch块和最后几条语句只写一次?
Is there any way to isolate those two lines with asterisks or have a common function, or rewrite the functions such that the try, catch block and last few statements are written only once?
这里的目标是尽量减少代码重复.
The objective here is to minimize code duplication.
public T Do<T>(Func<X, T> something)
{
try
{
var manager = CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2); //******
if (manager != null) return something(manager);
LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
}
catch (MyException exp)
{
ExceptionHandler.HandleRecoverableException(exp, LogTitle,
$"query on manager ({this}) failed.");
}
var msg = $"failed to query using manager ({this})!";
LoggingHandler.LogCritical(LogTitle, msg);
throw new MyException(msg);
}
public T Do<T>(Func<Y, T> something)
{
try
{
var manager = CoreInfrastructure.GetManager(Prefix, Config.Param3); //******
if (manager != null) return something(manager);
LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
}
catch (MyException exp)
{
ExceptionHandler.HandleRecoverableException(exp, LogTitle,
$"query on manager ({this}) failed.");
}
var msg = $"failed to query using manager ({this})!";
LoggingHandler.LogCritical(LogTitle, msg);
throw new MyException(msg);
}
推荐答案
创建接受管理器和函数的泛型方法
Create generic method that accepts manager and function
public T Do<T, TManager>(TManager manager, Func<TManager, T> something)
{
try
{
if (manager != null) return something(manager);
LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
}
catch (MyException exp)
{
ExceptionHandler.HandleRecoverableException(exp, LogTitle,
$"query on manager ({this}) failed.");
}
var msg = $"failed to query using manager ({this})!";
LoggingHandler.LogCritical(LogTitle, msg);
throw new MyException(msg);
}
public void DoAll<T>(Func<X, T> somethingX, Func<Y, T> somethingY)
{
Do(CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2), somethingX);
Do(CoreInfrastructure.GetManager(Prefix, Config.Param3), somethingY);
}
正如 Damien_The_Unbeliever 提到的,如果创建管理器可以是 MyException
的来源,您可以添加 Func
而不是 TManager 管理器:
As Damien_The_Unbeliever mentioned if creating manager can be source of MyException
you can add Func<TManager>
instead of TManager manager:
public T Do<T, TManager>(Func<TManager> managerCreate, Func<TManager, T> something)
{
try
{
TManager manager = managerCreate();
if (manager != null) return something(manager);
LoggingHandler.LogWarning(LogTitle, $"manager ({this}) is null.");
}
catch (MyException exp)
{
ExceptionHandler.HandleRecoverableException(exp, LogTitle,
$"query on manager ({this}) failed.");
}
var msg = $"failed to query using manager ({this})!";
LoggingHandler.LogCritical(LogTitle, msg);
throw new MyException(msg);
}
public void DoAll<T>(Func<X, T> somethingX, Func<Y, T> somethingY)
{
Do(() => CoreInfrastructure.GetManager(Prefix, Config.Param1, Config.Param2), somethingX);
Do(() => CoreInfrastructure.GetManager(Prefix, Config.Param3), somethingY);
}
您可以更进一步,将 Func
替换为参数化函数,其中传递 Prefix
和 Config
You can go further and replace Func<TManager>
with parametrized function where you pass Prefix
and Config
这篇关于跨通用函数隔离公共代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!