簡體   English   中英

通用Func <>作為基礎方法的參數

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM