尝试在foreach的EXPRESSION中捕获

时间:2015-05-07 07:39:32

标签: c# foreach try-catch

如何尝试/仅捕获foreach的表达式而不影响其他代码?

DoSomethingCodeA();
foreach (EXPRESSION) {
    DoSomethingCodeB();  
}
DoSomethingCodeC();

我不想尝试/捕获CodeA(),CodeB()和CodeC()中的内容,而只是在foreach语句中使用Expression部分。例如,我的表达式可能会失败,因为它动态加载SQL数据和SQL Server连接可能会中断。另一个例子是CodeB()可以修改用于foreach表达式的Collection,然后foreach中的行将失败,因为这是不允许的。等等,还有其他一些例子,为什么Expression会失败。在调用GetEnumerator,MoveNext访问Current或处理时......

那么,如何在C#中正确轻松地处理以尝试/捕获foreach循环的Expression部分内的东西?如果没有直接的语法,那么处理这种情况的最佳做法是什么?

2 个答案:

答案 0 :(得分:2)

如果将EXPRESSION中的任何功能移到新方法中,那么捕获异常变得很容易:

DoSomethingCodeA();
foreach (var x in SomeMethod()) 
{
    DoSomethingCodeB();  
}
DoSomethingCodeC();


private SomeType SomeMethod()
{
    try
    {
        get some piece of data from somewhere
        yield return data
    }
    catch (SomeException)
    {
        handle it
    }
}

答案 1 :(得分:2)

这是一种捕获异常的危险方式,因为它有很多边缘情况。

我理解它,因为你想要的行为是懒惰地返回几个值,如果在某个时刻获得下一个值会导致异常,那么你想要使该异常静音并停止返回值。

例如,如果有一个包含100个条目的数据库,您可能会遇到检索前60个条目,对这些条目执行某些操作(如复制到另一个数据库)以及在前60个条目之后的情况。连接丢失,以便在EXPRESSION内抛出异常。在这种情况下,期望的行为是什么? EXPRESSION是否应该停止产生价值,好像没有发生异常一样?是否要将您对前60个条目所做的更改回滚?

除非你有充分的理由不这样做,否则我建议你将结果缓存在查询中,然后在结果上运行foreach。这可确保您对所有相关条目执行操作,或者不在任何条目上执行操作。