增强C#语法糖(或绕过“不能使用ref或out参数”)

时间:2012-03-05 04:56:50

标签: c# .net lambda

请忽略这样的模式是否真的是个好主意。理由是我想捕获抛出的错误,或插入/更新/删除的记录数不匹配。我不想重复这个逻辑,当时这个定制感觉它只适用于不超过四个长“脚本”方法。

我的第一步是使用匿名函数。

public void DoSqlAction(Func<bool> f, string task, string ctx, ref bool cont, List<ResultInfo> resultInfo) {
    if (cont) {
        bool ret = false;
        try {
            if (f.Invoke()) {
                resultInfo.Add(new ResultInfo(seq, task, "Success", ctx, true));
                cont = true;
            } else {
                resultInfo.Add(new ResultInfo(seq, task, "Fail", ctx, false));
                cont = false;
            }
        } catch (Exception ex) {
            resultInfo.Add(new ResultInfo(seq, task, "Error: " + ex.Message, ctx, false));
            cont = false;
        }
    }
}

如果我尝试使用它:

 DoSqlAction(() => 1 == cx.Execute(someSql, anonymousTypeWithClassInstanceInside), "add item", refinfo.ToString(),ref cont, resultInfo);

anonymousTypeWithClassInstanceInside&lt; - 错误来源

出现错误:

  

不能在匿名方法,lambda表达式或查询表达式中使用ref或out参数'abc'

解决方案是摆脱委托Func<bool> f。我正在写这篇文章(也许它应该是一篇博文?)因为它觉得生成编译时错误是一个障碍。

在这篇文章中,我发现了Eric的文章链接:

C# Cannot use ref or out parameter inside an anonymous method body

这里

http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx

在看到foreach如何实现之后,我开始思考......嗯...也许我正在寻找可定制的语法糖。

现在C#4有可能吗? C#5有可能吗?它让我考虑在将来的某个时候调查http://nemerle.org,但我真的想留在C#中。

1 个答案:

答案 0 :(得分:0)

孤立地,编写此代码的更好方法是:

public ResultInfo DoSqlAction(Func<bool> f, string task, string ctx) {
    try {
        if (f.Invoke()) {
            return new ResultInfo(seq, task, "Success", ctx, true);
        } else {
            return new ResultInfo(seq, task, "Fail", ctx, false);
        }
    } catch (Exception ex) {
        return new ResultInfo(seq, task, "Error: " + ex.Message, ctx, false);
    }
}

在外面:

while (/* there's stuff to do */) {
    var result = DoSqlAction(/* the next stuff */);
    infos.Add(result);
    if (!result.Succeeded)
        break;
}

或等效物。这消除了奇怪的副作用函数,ref参数等。它更短。