C# foreach条件中引发的捕获异常
我有一个C# foreach条件中引发的捕获异常,c#,exception,foreach,try-catch,C#,Exception,Foreach,Try Catch,我有一个foreach循环,该循环在foreach自身的条件下在循环期间中断。有没有办法尝试捕获抛出异常的项,然后继续循环 这将运行几次,直到出现异常,然后结束 try { foreach(b in bees) { //exception is in this line string += b; } } catch { //error } 这根本不会运行,因为异常处于foreach的状态 foreach(b in bees) { //exception is in th
foreach
循环,该循环在foreach自身的条件下在循环期间中断。有没有办法尝试捕获抛出异常的项,然后继续循环
这将运行几次,直到出现异常,然后结束
try {
foreach(b in bees) { //exception is in this line
string += b;
}
} catch {
//error
}
这根本不会运行,因为异常处于foreach的状态
foreach(b in bees) { //exception is in this line
try {
string += b;
} catch {
//error
}
}
我知道你们中的一些人会问这是怎么发生的,下面是:
引发异常PrincipalOperationException
,因为在GroupPrincipal
(蜜蜂)中找不到Principal
(在我的示例中为b)
编辑:我添加了下面的代码。我还发现一个组成员指向一个不再存在的域。我通过删除该成员轻松解决了这个问题,但我的问题仍然存在。如何处理在foreach条件内抛出的异常
PrincipalContext ctx = new PrincipalContext(ContextType.domain);
GroupPrincipal gp1 = GroupPrincipal.FindByIdentity(ctx, "gp1");
GroupPrincipal gp2 = GroupPrincipal.FindByIdentity(ctx, "gp2");
var principals = gp1.Members.Union(gp2.Members);
foreach(Principal principal in principals) { //error is here
//do stuff
}
也许您可以尝试创建这样的方法:
public IEnumerable<T> TryForEach<T>(IEnumerable<T> list, Action executeCatch)
{
if (list == null) { executeCatch(); }
IEnumerator<T> enumerator = list.GetEnumerator();
bool success = false;
do
{
try
{
success = enumerator.MoveNext();
}
catch
{
executeCatch();
success = false;
}
if (success)
{
T item = enumerator.Current;
yield return item;
}
} while (success);
}
与@Guillaume的回答几乎相同,但“我更喜欢我的”:
公共静态类扩展
{
公共静态IEnumerable TryForEach(此IEnumerable序列,操作处理程序)
{
if(sequence==null)
{
抛出新的ArgumentNullException(“序列”);
}
if(handler==null)
{
抛出新的ArgumentNullException(“处理程序”);
}
var mover=sequence.GetEnumerator();
布尔更多;
尝试
{
more=mover.MoveNext();
}
捕获(例外e)
{
处理程序(e);
屈服断裂;
}
而(更多)
{
收益率;收益率;收益率;收益率;
尝试
{
more=mover.MoveNext();
}
捕获(例外e)
{
处理程序(e);
屈服断裂;
}
}
}
}
问题不在“状况”中。它正在枚举bees
对象。出于调试目的,请尝试“手动”枚举bees
。它是某种IEnumerable
或IEnumerable
。手动执行.MoveFirst()
并查看是否立即获得异常。哇,我没意识到C#s在下一个月没有简历。。。我刚刚发现所有这些论坛的家伙都在寻找类似的东西。我想这只是成为VB.net开发人员的另一件好事。我的道歉mates@mellamokb,其实我自己也不怎么用。我曾经和一个非常有趣的C++程序员合作过,他被迫在Vb.net写,他会在错误的简历上乱扔乱码。为什么我要在这里做点什么?这里有人在使用它。你能提供你的实际代码吗,即至少涉及到的实际类(你的意思是?因为我看不出它甚至是可枚举的)。也许我们可以为您的问题找到一个更“特定于域”的解决方案,这最终可能比“通用”的情况更容易;已经枚举了完整的列表,而for循环也是枚举枚举的错误方式。我猜它不起作用,因为list.Count()已经抛出错误消息。此外,为什么要枚举器.MoveNext();抛出异常后返回一个正确的值?@user287107您是对的。我改进了要处理的代码,以处理Count()
问题。@JohnSaunders OP谈论的是一些GroupPrincipal
。为了进行枚举,我只使用了该类的GetMembers
方法。但它实际上可以是任何东西…我也更喜欢我的。。。但是,如果没有枚举,抛出异常比执行操作
更有意义。首先执行MoveNext
而不是在循环中执行它的原因是什么?@guillome:没什么大不了的,但是这样循环中间就没有回报了。这是一个很小的风格问题,不需要考虑太多。别忘了处理枚举器!
foreach (var bee in TryForEach(bees.GetMembers(), () => { Console.WriteLine("Error!"); }))
{
}
public static class Extensions
{
public static IEnumerable<T> TryForEach<T>(this IEnumerable<T> sequence, Action<Exception> handler)
{
if (sequence == null)
{
throw new ArgumentNullException("sequence");
}
if (handler == null)
{
throw new ArgumentNullException("handler");
}
var mover = sequence.GetEnumerator();
bool more;
try
{
more = mover.MoveNext();
}
catch (Exception e)
{
handler(e);
yield break;
}
while (more)
{
yield return mover.Current;
try
{
more = mover.MoveNext();
}
catch (Exception e)
{
handler(e);
yield break;
}
}
}
}