我能否在一个catch块中使用多个try块?

3

我正在制作一个国际象棋游戏。我想知道是否可以删除代码中的这些空 catch 块,将所有 try 块放在同一范围内并进入单个 catch 块,因为我认为这看起来有点愚蠢和杂乱无章。

我的代码:

for (int i = 1; i < 8; i++)
{
    try
    {
        if (board[x + i, y].Equals(blackColor))
            checkmateList.AddLast(placementBoard[x + i, y]);//Moving Right
    }
    catch
    {

    }

    try
    {
        if (board[x - i, y].Equals(blackColor))
            checkmateList.AddLast(placementBoard[x - i, y]);//Moving Left
    }
    catch
    {

    }

    try
    {
        if (board[x, y + i].Equals(blackColor))
            checkmateList.AddLast(placementBoard[x, y + i]);//Moving Down
    }
    catch
    {

    }
}

我有一些空的catch块,因为我只会得到一个数组越界异常,因为它将超出边界,所以我只能停止搜索并转向不同的区域,但我认为这看起来很愚蠢,因为我的大部分代码都是用这种方式移动棋子。


2
为什么不检查边界而是吞掉异常呢?那将是一个更好的方法。 - Charles Mager
3
不要使用异常来控制应用程序流程! - Hackerman
将for循环放入异常处理程序中,并摆脱for循环内部的异常处理程序。 - jdweng
那么,Charles,你的意思是取x或y值并将其减去8,然后运行循环那么多次? - Doomed Space
你期望捕获哪些异常?如果你使用它们来检测索引越界条件,那么在调用索引器之前_请先检查一下_。这样会更简单,而且不会有异常的性能开销。 - D Stanley
显示剩余2条评论
3个回答

3

单个 try 块可以有多个 catch 块,而我们不能在多个 try 块中使用同一个 catch 块。但是您可以将整个内容放在一个 Try-Block 中并使用单个 catch 块,不需要为每个语句分别放置 try 块。此外,在捕获异常后继续执行不是一个好的实践。尝试像这样做:

 try
 {
    for (int i = 1; i < 8; i++)
    {

       // all conditions and statements here
    }
 }
 catch
 {
      // handle exception here
 }

在这种情况下,我们可以期望出现IndexOutOfRangeException异常,但是我们可以通过条件语句简单地跳过获取异常的机会,这样代码应该像这样:
for (int i = 1; i < 8; i++)
{
    if (x + i < 8 && board[x + i, y].Equals(blackColor))
        checkmateList.AddLast(placementBoard[x + i, y]); //Moving Right

    if (x - i >= 0 && board[x - i, y].Equals(blackColor))
        checkmateList.AddLast(placementBoard[x - i, y]); //Moving Left

    if (y + i < 8 && board[x, y + i].Equals(blackColor))
        checkmateList.AddLast(placementBoard[x, y + i]); //Moving Down
}

这将产生与原始代码不同的结果。在原始代码中,如果向左移动导致异常,它仍将向右移动和向下移动。但是,您的代码将在其中一个移动失败时立即退出。 - gunnerone
谢谢,我已经更新了答案。你不需要获取边界,因为它总是8,因为这是一个棋盘。 - sujith karivelil
谢谢,我最近刚刚输入了我发布的代码,因为我没有寻找国王并搜索导致将军的棋子,而是制作了一个算法来搜索每个棋子的移动集,如果它导致国王,它将运行我为将军制作的代码,但那段代码真的很糟糕。大约有1000行左右,所以我决定放弃它并重新开始。我现在才意识到我从未增加x或y,所以两个变量都停留在0。 - Doomed Space

2
您IP地址为146.190.162.183,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。
for (int i = 1; i < 8; i++)
{
    if (x + i < board.GetLength(0) && board[x + i, y].Equals(blackColor))
        checkmateList.AddLast(placementBoard[x + i, y]); //Moving Right

    if (x - i >= 0 && board[x - i, y].Equals(blackColor))
        checkmateList.AddLast(placementBoard[x - i, y]); //Moving Left

    if (y + i < board.GetLength(1) && board[x, y + i].Equals(blackColor))
        checkmateList.AddLast(placementBoard[x, y + i]); //Moving Down
}

1

流程控制的异常=不好的想法。它们用于找到问题,而不是引起问题。

回答原始问题,您可以嵌套try/catch块。

try{  try{ condition; } catch { response(); } catch {response2();}

现在,我们来按照正确的方式来做。在方法外面,让我们执行以下操作:
        public enum Directions 
        {
            Right, 
            Left, 
            Down
        }

现在,让我们使用它。
for (int i = 1; i < 8; i++)
{
    bool right, left, down;
     right =  board[x + i, y].Equals(blackColor);
     left = board[x + i, y].Equals(blackColor);
     down = board[x - i,y].Equals(blackColor)    
    var direction = new List<bool>() { right, left, down }


    for(i = 0; i < direction.Count, i++) 
    {
      try    
       {  
             if(direction[i])
             {
                  switch(i)
                  {
                     case Directions.Right: checkmateList.AddLast(placementBoard[x + i, y]); break;
                     case Directions.Left: checkmateList.AddLast(placementBoard[x - i, y];); break;
                     case Directions.Down: checkmateList.AddLast(placementBoard[x, y + i]); break;
                     default:
                            throw new ApplicationException("oops");
                            break; //not needed but i prefer to keep breaks in anyway       
                  }
             }  
       } catch (Exception ex){ //do stuff; }
    }

}
虽然格式不太美观,但这就是它。如果正确使用索引和枚举,它们可以成为很好的伙伴。


我不知道如何使用枚举,而且就在两天前我才刚刚学会了switch。此外,我只发布了3个移动作为样本,我正在处理的每个棋子都有每个移动,所以这将是很多布尔值,更不用说我还要使用白色棋子。 - Doomed Space
枚举基本上是为数字命名。在我发布的代码中,我将布尔值放入可能性列表中,并有意将列表中的索引与枚举所表示的数字匹配(Directions.Right == 0)。由于在国际象棋中有许多类型的移动,我建议您创建一个名为Moves的类,并将您的移动样式逻辑放在那里。然后,您可以调用例如Moves.Knight.ForwardRight(),这个棋子向前移动两个位置并向右移动一个位置。Moves.Queen.DownLeft(x)可以将皇后移动x个空间。 - CDove
我为每个棋子编写了一个类,它会执行其移动。 - Doomed Space

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