如果在列表中引发异常.对于每个,迭代是否停止
本文关键字:于每个 迭代 是否 列表 异常 如果 | 更新日期: 2023-09-27 18:34:21
如果我有以下代码:
List<MyClass> list = GetList();
list.ForEach(i => i.SomeMethod());
假设SomeMethod()
抛出了一个异常。ForEach
继续迭代,还是就停在那里?
如果它确实终止,有没有办法让集合中的其余项运行其方法?
是的,如果引发异常,循环将退出。如果不希望出现这种行为,则应将异常处理放入委托中。您可以轻松地为此创建一个包装器方法:
public static Action<T> SuppressExceptions<T>(Action<T> action)
{
return item =>
{
try
{
action(item);
}
catch (Exception e)
{
// Log it, presumably
}
};
}
老实说,如果可能的话,我会尽量避免这种情况。捕获所有这样的异常是不愉快的。它也不会记录失败的项目或异常等。您确实需要更详细地考虑您的要求:
- 您需要收集失败的项目吗?
- 是否需要收集异常?
- 您要捕获哪些异常?
几乎可以肯定的是,创建一个单独的方法,该方法使用正常的foreach
循环,处理错误并收集错误。就我个人而言,我通常更喜欢使用foreach
而不是ForEach
- 您可能也希望阅读Eric Lippert对此的看法。
它会抛出一个错误。您也正在重新实施foreach
。怎么样只是:
foreach (var item in list)
{
try
{
// dangerous thing with item
}
catch (Exception e)
{
// how do you want to log this?
}
}
这样做的好处是在大多数版本的 .NET 中工作,并且明显会产生副作用。当然,您可以将此代码直接放在ForEach
委托中,但我只建议如果它本身是一个方法(而不是 lambda 函数)。
一个合理的替代方法是创建自己的ForEachWithCatch
扩展,用于捕获所有异常并将其发送回调用方:
public static IEnumerable<Tuple<T,Exception>> ForEachWithCatch<T>(this IEnumerable<T> items, Action<T> action)
{
var exceptions = new List<Tuple<T,Exception>>();
foreach(var item in items)
{
try
{
action(item);
}
catch(Exception e)
{
exceptions.Add(Tuple.Create(item, e));
}
}
return exceptions;
}
这会发回每个失败项的枚举项及其相应的异常。
如果你的SomeMethod
已经实现了try-catch块,那么foreach将继续
void SomeMethod()
{
try
{
//Some operation on i
}
catch(Exception ex)
{
}
}
但如果不是,那么 foreach 就会崩溃。
一是这样做的
list.ForEach(i =>
{
try
{
i.SomeMethod();
}
catch(Exception ex)
{
}
});
但是在你的代码中有零 try-catch 块总是好的。否则你永远不会找到罪魁祸首在哪里。