如何在C#中高效地打破双重循环?

4

这是我目前用来跳出双重循环并继续执行 DoStuff() 的方法:

foreach (var enemyUnit in nearbyEnemyUnits) {
    var skip = false;
    foreach (var ownUnit in ownUnits) {
        if (ownUnit.EngagedTargetTag == enemyUnit.tag) {
            skip = true;
            break;
        }
    }

    if (skip) continue;

    DoStuff(enemyUnit);
}

整个“定义一个临时布尔变量来检查跳过”的方法对我来说似乎非常hacky。在像Go这样的语言中,我可以使用标签来退出循环,甚至可以使内部循环成为clojure的一部分。在C#中最好的方法是什么?
我一直像上面的例子那样做了很长时间,感觉一定有更好的方法 - 现在几乎感到羞愧地问。
谢谢

一些编程语言添加了标记循环以避免使用goto,但C#保留了goto - harold
3个回答

5
你可以使用 goto、匿名方法,将其封装在一个方法中,或者使用 C#7 中的局部函数。
static void Main(string[] args)
{
   void localMethod()
   {
      foreach (var enemyUnit in nearbyEnemyUnits)
         foreach (var ownUnit in ownUnits)
            if (ownUnit.EngagedTargetTag == enemyUnit.tag)
               return;
   }

   localMethod();
}

额外资源


哦,这很有趣,我完全忘记了在C#中goto是一种东西。使用什么更符合习惯?本地方法还是GoTo? - Muppet
仅返回本地方法使用的翻译文本。 - M.Armoun
@Muppet 这大概是我唯一感到使用goto语句比较舒适的时候,即使这样,它也会让我毛骨悚然。 - TheGeneral
@Muppet 我个人会选择使用本地方法。 - TheGeneral
感谢大家的回答,我希望我能接受所有的答案,但是这个似乎对我的问题最有效! - Muppet

3

为什么要使用goto,而不是使用linq呢?

foreach (var enemyUnit in nearbyEnemyUnits.Where(e=>ownUnits.Any(e1=>e1.EngagedTargetTag == e.Tag) == false))
                DoStuff(enemyUnit);

LINQ不是比上面的循环慢一点吗?我每秒钟要调用这个函数很多次,所以它需要非常高效。在你的意见中,LINQ仍然是更好的选择吗? - Muppet
根据我挖掘出来的一篇旧文章,LINQ语句并不比foreach循环慢。如果你关心速度,你应该使用for循环。但是LINQ更容易阅读,可读性有助于在未来几周/年回到这段代码并弄清楚你做了什么。https://dev59.com/s3A75IYBdhLWcg3wsrSD http://www.schnieds.com/2009/03/linq-vs-foreach-vs-for-loop-performance.html - Paul Hebert

1

我已经很久没有使用过goto了,但在C#中可以使用。以下是一个示例(最后的归属链接):

public class GotoTest1
{
    static void Main()
    {
        int x = 200, y = 4;
        int count = 0;
        string[,] array = new string[x, y];

        // Initialize the array:
        for (int i = 0; i < x; i++)

            for (int j = 0; j < y; j++)
                array[i, j] = (++count).ToString();

        // Read input:
        Console.Write("Enter the number to search for: ");

        // Input a string:
        string myNumber = Console.ReadLine();

        // Search:
        for (int i = 0; i < x; i++)
        {
            for (int j = 0; j < y; j++)
            {
                if (array[i, j].Equals(myNumber))
                {
                    goto Found;
                }
            }
        }

        Console.WriteLine("The number {0} was not found.", myNumber);
        goto Finish;

    Found:
        Console.WriteLine("The number {0} is found.", myNumber);

    Finish:
        Console.WriteLine("End of search.");


        // Keep the console open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/goto


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接