繁体   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