[英]Generic Func<> as parameter to base method
我可能会失去情节,但我希望有人能指出我正确的方向。
我想做什么?
我正在尝试编写一些使用Func <>和Action的基本方法,以使这些方法可以处理所有异常处理等。因此,它不会在所有地方重复出现,但允许派生类指定要执行的操作。
到目前为止,这是基类。
public abstract class ServiceBase<T>
{
protected T Settings { get; set; }
protected ServiceBase(T setting)
{
Settings = setting;
}
public void ExecAction(Action action)
{
try
{
action();
}
catch (Exception exception)
{
throw new Exception(exception.Message);
}
}
public TResult ExecFunc<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function)
{
try
{
/* what goes here?! */
}
catch (Exception exception)
{
throw new Exception(exception.Message);
}
}
}
我想在派生类中以以下方式执行操作(这似乎有效):
public void Delete(string application, string key)
{
ExecAction(() => Settings.Delete(application, key));
}
我想在派生类中以类似的方式执行Func,但就我的一生而言,我似乎无法锻炼基础类中的内容。
我希望能够通过以下方式调用它(如果可能):
public object Get(string application, string key, int? expiration)
{
return ExecFunc(() => Settings.Get(application, key, expiration));
}
我是不是觉得太疯狂了,或者这可能吗? 在此先感谢您提供的所有帮助。
首先,您在这里对异常所做的操作可能不是一个好主意。 几乎所有您想要的东西都无法捕获所有异常。
但是对于您通常所做的事情,您已经使用Action
解决了该问题。 为了方便起见,您只需要对Func
进行改进即可调用Action
版本:
public static TResult ExecFunc<TResult>(Func<TResult> func)
{
TResult result = default(TResult);
ExecAction(() => result = func());
return result;
}
无需提供传递参数的方法,因为闭包已经解决了该问题:
var someData = "Hi!";
var result = ExecFunc(() => SomeOtherMethod(someData));
// the lambda can close over the local variables of the outer scope
请注意我如何使该方法静态化,因为它看起来像ExecAction
也可能是静态的,因为它不引用任何实例成员。 如果方法是静态的,则将它们移动到单独的static
类中可能会更清楚。
public void Delete(string application, string key)
{
ExecAction(() => Settings.Delete(application, key));
}
public object Get(string application, string key, int? expiration)
{
return ExecFunc(() => Settings.Get(application, key, expiration));
}
// ...
public TResult ExecFunc<TResult>(Func<TResult> func)
{
try
{
return func();
}
catch (Exception exception)
{
throw new Exception(exception.Message);
}
}
顺便说一句,您的异常处理看起来有些狡猾:首先,捕获Exception
本身并不是一种好的做法。 考虑改为捕获更具体的异常。 其次,您在catch
块中引发了一个新异常,这意味着您将丢失原始异常中的stacktrace等。 您应该使用throw;
而是重新抛出原始异常。 (这假设您的catch
块正在执行某种有用的工作。如果您要做的只是捕获和抛出,那么就完全放弃try...catch
块。)
public TResult ExecFunc<T1, T2, T3, TResult>(Func<T1, T2, T3, TResult> function, T1 t1Param, T2 t2Param, T3 t3Param)
{
try
{
return function(t1Param, t2Param, t3Param);
}
catch (Exception exception)
{
throw new Exception(exception.Message);
}
}
然后,您可以这样称呼它:
public object Get(string application, string key, int? expiration)
{
return ExecFunc(Settings.Get, application, key, expiration);
}
public object Get(string application, string key, int? expiration)
{
object result = null;
ExecAction(() => result = Settings.Get(application, key, expiration));
return result
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.