我可能会失去情节,但我希望有人可以指出我正确的方向。
我想做什么?
我正在尝试编写一些基本方法,这些方法采用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);
}
}
}
我想在派生类中以下列方式执行Action(这似乎有效):
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));
}
我是在想太疯狂还是这可能?提前感谢所有的帮助。
答案 0 :(得分:4)
首先,你在这里做的异常可能是一个坏主意。所有例外的一般情况都不是你想要的。
但至于你正在做什么,你已经用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
类中会更清楚。
答案 1 :(得分:3)
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
块中抛出一个新的异常,这意味着你从原始异常中丢失了堆栈跟踪等。您应该使用throw;
代替重新抛出原始异常。 (这假设你的catch
块正在做一些有用的工作。如果你所做的只是捕捉和投掷,那么就完全抛弃try...catch
块。)
答案 2 :(得分:1)
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);
}
答案 3 :(得分:0)
public object Get(string application, string key, int? expiration)
{
object result = null;
ExecAction(() => result = Settings.Get(application, key, expiration));
return result
}