为了账号安全,请及时绑定邮箱和手机立即绑定

实现不带参数的调用委托

实现不带参数的调用委托

C#
吃鸡游戏 2021-05-02 17:09:44
我尝试实现一个装饰器模式来处理数据库事务中的错误。我没有使用标准Func和Actions的问题,但是使用具有参数的函数时遇到了困难。这里有许多问题相同的问题,我想实现自己的代表:    public delegate TResult FuncWithOut<T1, T2, TResult>(T1 arg1, out T2 arg2);         1)但我没有发现如何基于此委托来实现方法:    private void SafetyExecuteMethod(Action action)    {        try        {            action();        }        catch (Exception ex)        {            // Some handling        }    }    private T SafetyExecuteFunction<T>(Func<T> func)    {        T result = default(T);        SafetyExecuteMethod(() => result = func.Invoke());        return result;    }    private SafetyExecuteFunctionWithOut // ??    {        // ??    }2)以及如何调用此方法:    public bool UserExists(string name)    {        return SafetyExecuteFunction(() => _innerSession.UserExists(name));    }    public void CreateUser(string name, string password)    {        SafetyExecuteMethod(() => _innerSession.CreateUser(name, password));    }    public bool CanUpdateUser(string userName, out string errorMessage)    {        // ??        // _innerSession.CanUpdateUser(userName, out errorMessage);    }
查看完整描述

1 回答

?
慕妹3242003

TA贡献1824条经验 获得超6个赞

只需使用与的示例相同的方案即可SafetyExecuteFunction<T>(Func<T> func)。


您需要注意的一件事是,您需要为out参数使用一个临时的局部变量。


private TResult SafetyExecuteFunctionWithOut<T1, T2, TResult>(FuncWithOut<T1, T2, TResult> func, T1 arg1, out T2 arg2)

{

    TResult result = default(TResult);

    T2 arg2Result = default(T2); // Need to use a temporary local variable here 


    SafetyExecuteMethod(() => result = func(arg1, out arg2Result));


    arg2 = arg2Result; // And then assign it to the actual parameter after calling the delegate.

    return result;

}

调用该函数的确像这样工作:


public bool CanUpdateUser(string userName, out string errorMessage)

{

    bool result = SafetyExecuteFunctionWithOut<string, string, bool>(_innerSession.CanUpdateUser, userName, out errorMessage);

    return result;

}

请注意,您必须将其_innerSession.CanUpdateUser作为参数传递给,SafetyExecuteFunctionWithOut而不是使用lambda表达式。


使用幼稚的尝试:


private TResult SafetyExecuteFunctionWithOut<T1, T2, TResult>(FuncWithOut<T1, T2, TResult> func, T1 arg1, out T2 arg2)

{

    TResult result = default(TResult);


    SafetyExecuteMethod(() => result = func(arg1, out arg2));


    return result;

}

创建错误消息:


CS1628无法在匿名方法,lambda表达式或查询表达式中使用ref或out参数“ arg2”


此答案中说明了为什么不允许您这样做。


查看完整回答
反对 回复 2021-05-08
  • 1 回答
  • 0 关注
  • 181 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信