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

C# 增强C语法糖分(或绕过“不能使用ref或out参数”),c#,.net,lambda,C#,.net,Lambda,请忽略这样的模式是否是一个好主意。理由是我想捕获抛出的错误,或者插入/更新/删除的记录数量不匹配。我不想重复这个逻辑,当时这种定制感觉只适用于四种长脚本方法 我的第一步是使用匿名函数 public void DoSqlAction(Func<bool> f, string task, string ctx, ref bool cont, List<ResultInfo> resultInfo) { if (cont) { bool ret = fa

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

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

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;
        }
    }
}

anonymousTypeWithClassInstanceInside单独编写此代码的更好方法是:

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);
    }
}

或同等标准。这消除了奇怪的副作用函数、ref参数等,并且更短。

单独编写此代码的更好方法是:

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);
    }
}

或同等标准。这消除了奇数的副作用函数、ref参数等,而且更短。

考虑+1只是为了……感觉生成的编译时错误有点像路障。我不明白为什么您不能在这里返回true或false,并在一个调用方法中确定continuation,该调用方法以SqlActions列表作为输入-是否有其他代码实际使用cont?您到底为什么不编写它来返回true或false以表示成功或失败,而不是使用ref参数?或者返回一个ResultInfo。我错过了什么吗?@arootbeer:同意。这就是我所说的删除函数f的意思。这正是本例中代码的演变方式,在实现了一个可重用的模式之后,我必须去改变一切。bool的想法不如lamda灵活。。。如果我们最终找到了一个我们想要实现的跨领域模式呢?找到这一点后,我倾向于总是使用某种OO模式,而不是基于语言的想法。。。。LAMDA是功能强大的小型设备。我不喜欢被这样的事情绊倒。也许它和lamda材料有关。我不会评论你写的代码是否好。但它应该很好。由于lambda表达式中没有任何ref或out,我认为您的问题不在您发布的代码中。考虑+1只是为了…感觉生成的编译时错误[那]是一个障碍。我不明白为什么您不能在这里返回true或false,并在一个调用方法中确定continuation,该调用方法以SqlActions列表作为输入-是否有其他代码实际使用cont?您到底为什么不编写它来返回true或false以表示成功或失败,而不是使用ref参数?或者返回一个ResultInfo。我错过了什么吗?@arootbeer:同意。这就是我所说的删除函数f的意思。这正是本例中代码的演变方式,在实现了一个可重用的模式之后,我必须去改变一切。bool的想法不如lamda灵活。。。如果我们最终找到了一个我们想要实现的跨领域模式呢?找到这一点后,我倾向于总是使用某种OO模式,而不是基于语言的想法。。。。LAMDA是功能强大的小型设备。我不喜欢被这样的事情绊倒。也许它和lamda材料有关。我不会评论你写的代码是否好。但它应该很好。由于lambda表达式中没有任何ref或out,我认为问题不在您发布的代码中。最初ref bool cont,List resultInfo是闭包的一部分。函数被本地包装。因此,这种方法更加优雅,对于一个较长的脚本来说是有意义的。当您试图将ref类型(即类实例)传递给Func f时,就会出现问题。所以这个答案是行不通的。我仍然不明白为什么作为闭包的一部分会使这个解决方案出错;也许如果你提供更多的上下文,它会变得清晰?正确的结束语评论。我的结束语应该是关于优雅的,我本应该留在这个话题上。问题出现在c-DoSqlActionmethodstring中,新的{a=1,b=2,c=newclassabc1,2,3,4}最初ref bool cont,List resultInfo是闭包的一部分。函数被本地包装。因此,这种方法更加优雅,对于一个较长的脚本来说是有意义的。当您试图将ref类型(即类实例)传递给Func f时,就会出现问题。所以这个答案是行不通的。我仍然不明白为什么作为闭包的一部分会使这个解决方案出错;也许如果你提供更多的上下文,它会变得清晰?正确的结束语评论。我的结束语应该是关于优雅的,我本应该留在这个话题上。问题出现在c-DoSqlActionmethodstring中,新的{a=1,b=2,c=newclassabc1,2,3,4}
while (/* there's stuff to do */) {
    var result = DoSqlAction(/* the next stuff */);
    infos.Add(result);
    if (!result.Succeeded)
        break;
}