在正常循环中,您可以使用break中断循环。可以使用匿名代理完成同样的工作吗?
实施例 inputString和result都在委托之外声明。
blackList.ForEach(new Action<string>(
delegate(string item)
{
if(inputString.Contains(item)==true)
{
result = true;
// I want to break here
}
}
));
编辑: 感谢回复,我实际上是在约翰那时读你的书:)为了记录,我点击这个问题并切换回正常的foreach循环,但我发布了这个问题,看看我是否错过了什么。
答案 0 :(得分:37)
正如其他人发布的那样,你无法在ForEach中退出循环。
你能使用LINQ吗?如果是这样,您可以轻松地将TakeWhile和自定义ForEach扩展方法结合起来(几乎每个项目似乎都有这些日子)。
但是,在您的示例中,List<T>.FindIndex
将是最佳选择 - 但如果您实际上没有这样做,请发布您 想要做的事情的示例。< / p>
答案 1 :(得分:27)
没有可以访问的循环,从中可以断开。每次调用(匿名)委托都是一个新的函数调用,因此局部变量无济于事。但是,由于C#给你一个闭包,你可以设置一个标志,然后在进一步的调用中什么都不做:
bool stop = false;
myList.ForEach((a) => {
if (stop) {
return;
} else if (a.SomeCondition()) {
stop = true;
}
});
(需要对此进行测试以检查是否生成了关闭的正确引用语义。)
更高级的方法是创建自己的扩展方法,允许委托返回false来停止循环:
static class MyExtensions {
static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
foreach (T t in input) {
if (!action(t)) {
break;
}
}
}
}
答案 2 :(得分:15)
你有LINQ可用吗?你的逻辑似乎与Any:
类似bool any = blackList.Any(s=>inputString.Contains(s));
与:
相同bool any = blackList.Any(inputString.Contains);
如果你没有LINQ,那么它仍然是:
bool any = blackList.Find(inputString.Contains) != null;
如果你想运行其他逻辑,你可以用TakeWhile
等来做(使用LINQ)
答案 3 :(得分:6)
在使用ForEach方法时,我认为没有一种优雅的方法。一个hacky解决方案是抛出异常。
什么阻止你做一个老式的foreach?
foreach (string item in blackList)
{
if (!inputString.Contains(item)) continue;
result = true;
break;
}
答案 4 :(得分:3)
如果你想要一个循环,请使用循环。
Action
允许没有返回值,因此ForEach函数无法知道您想要中断,除非抛出异常。在这里使用例外是过度的。
答案 5 :(得分:2)
“退出”循环的唯一方法是抛出异常。没有“破解”方式退出.ForEach方法,就像普通的foreach循环一样。
答案 6 :(得分:2)
ForEach方法并不意味着这样做。如果您想知道集合是否包含项目,则应使用Contains方法。如果你想对集合中的所有项目进行检查,你应该尝试使用Any extention方法。
答案 7 :(得分:1)
class Program
{
static void Main(string[] args)
{
List<string> blackList = new List<string>(new[] { "jaime", "jhon", "febres", "velez" });
string inputString = "febres";
bool result = false;
blackList.ForEach((item) =>
{
Console.WriteLine("Executing");
if (inputString.Contains(item))
{
result = true;
Console.WriteLine("Founded!");
}
},
() => result);
Console.WriteLine(result);
Console.ReadLine();
}
}
public static class MyExtensions
{
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action, Func<bool> breakOn)
{
foreach (var item in enumerable)
{
action(item);
if (breakOn())
{
break;
}
}
}
}
答案 8 :(得分:1)
bool @break = false;
blackList.ForEach(item =>
{
if(!@break && inputString.Contains(item))
{ @break = true;
result = true;
}
if (@break) return;
/* ... */
});
请注意,上述内容仍将遍历每个项目,但会立即返回。当然,这种方式可能不如普通的 foreach
那么好。
答案 9 :(得分:1)
如果您真的希望在列表中存在循环foreach,则可以使用此代码中的异常:
public class ExitMyForEachListException : Exception
{
public ExitMyForEachListException(string message)
: base(message)
{
}
}
class Program
{
static void Main(string[] args)
{
List<string> str = new List<string>() { "Name1", "name2", "name3", "name4", "name5", "name6", "name7" };
try
{
str.ForEach(z =>
{
if (z.EndsWith("6"))
throw new ExitMyForEachListException("I get Out because I found name number 6!");
System.Console.WriteLine(z);
});
}
catch (ExitMyForEachListException ex)
{
System.Console.WriteLine(ex.Message);
}
System.Console.Read();
}
}
希望这有助于获得其他观点。
答案 10 :(得分:0)
这对你有用吗?
bool result = null != blackList.Find( item => inputString.Contains(item)) );
答案 11 :(得分:-2)
blackList.ForEach(new Action<string>(
delegate(string item)
{
if(inputString.Contains(item)==true)
{
result = true;
// I want to break here
return;
}
}
));