[英]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.