请忽略这样的模式是否真的是个好主意。理由是我想捕获抛出的错误,或插入/更新/删除的记录数不匹配。我不想重复这个逻辑,当时这个定制感觉它只适用于不超过四个长“脚本”方法。
我的第一步是使用匿名函数。
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
这里
在看到foreach如何实现之后,我开始思考......嗯...也许我正在寻找可定制的语法糖。
现在C#4有可能吗? C#5有可能吗?它让我考虑在将来的某个时候调查http://nemerle.org,但我真的想留在C#中。
答案 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参数等。它更短。