Generic Func 作为基本方法的参数

我可能会失去情节,但我希望有人可以指出我正确的方向。

我想做什么?

我正在尝试编写一些基本方法,这些方法采用Func 和Action,以便这些方法处理所有异常处理等,因此它不会在所有地方重复,但允许派生类指定它想要执行的操作。

到目前为止,这是基类。

public abstract class ServiceBase { 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(Func 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)); } 

我是在想太疯狂还是这可能? 在此先感谢您的帮助。

 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(Func func) { try { return func(); } catch (Exception exception) { throw new Exception(exception.Message); } } 

顺便说一句,你的exception处理看起来有点狡猾:首先,捕获Exception本身并不是一种好的做法。 请考虑捕获更具体的exception。 其次,你在catch块中抛出一个新的exception,这意味着你从原始exception中丢失了堆栈跟踪等。 你应该使用throw; 而是重新抛出原始exception。 (这假设你的catch块正在做一些有用的工作。如果你所做的只是捕捉和投掷,那么就完全抛弃try...catch块。)

首先,你在这里做exception的事情可能是一个坏主意。 所有例外的一般情况都不是你想要的。

但至于你正在做什么,你已经解决了Action的问题。 为方便起见,您只需要对Func进行细化即可调用Action版本:

 public static TResult ExecFunc(Func 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 TResult ExecFunc(Func 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 }