【问题标题】:Can I have multiple try blocks with a single catch block我可以有多个 try 块和一个 catch 块吗
【发布时间】:2017-01-12 16:56:36
【问题描述】:

我正在做一个国际象棋游戏,我只是想知道我是否可以在我的代码中摆脱这些空的 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 块,因为我得到的唯一错误是越界异常,因为它会退出董事会,所以我只是停止搜索并进入不同的区域,但我认为它看起来很愚蠢,因为大多数我的使碎片移动的代码包括这个。

【问题讨论】:

  • 为什么不检查边界而不是吞下异常?那将是一个更好的方法。
  • 不要使用异常来控制应用程序流!
  • 将for循环放入一个异常处理程序中,去掉for循环内的异常处理程序。
  • 查尔斯,您的意思是取 x 或 y 值,然后将其减去 8 并多次运行循环?
  • 是的,或者至少在尝试之前检查是否可行。为您无法预测的事情保留例外情况,例如无法访问用户要求您打开的文件。

标签: c# exception try-catch


【解决方案1】:

单个try 可以使用多个catch,而我们不能使用一个catch 进行多次尝试,但是您可以将整个内容包含在一个带有单个catch 的Try-Block 中,无需将每个语句包含在单独的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
}

【讨论】:

  • 这会产生与原始代码不同的结果。在原始代码中,如果向左移动导致异常,它仍然会向右移动并向下移动。一旦其中一个动作失败,您的代码就会退出。
  • 谢谢我已经更新了答案。你不需要得到边界,因为它总是8,因为它是一个棋盘
  • 谢谢,我刚刚输入了我发布的代码,因为我没有找到国王并搜索导致将死的棋子,而是创建了一个算法来搜索每个棋子移动集,如果它导致国王它会运行我为将死制作的代码,但该代码简直太糟糕了。这是一个很好的 1000 行,所以我决定放弃它并重新开始。我刚刚意识到我从来没有增加 x 或 y 所以两个变量都在 0
【解决方案2】:

正如其他人所提到的,最好删除 try/catch 并测试移动是否在棋盘上。

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
}

【讨论】:

    【解决方案3】:

    流控制的例外 = 坏主意。他们是为了发现问题,而不是造成问题。

    要回答原始问题,您可以嵌套 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; }
        }
    

    }
    不是我最漂亮的格式,但你去。 Indeces 和 enums 可以让好朋友做得对。

    【讨论】:

    • 我不知道如何使用枚举,我只是在 2 天前真正了解了开关,我也只发布了 3 个动作作为示例,我在这里拥有每件作品的每一个动作我一起工作,所以这将是很多布尔值,更不用说我还必须使用白色块。
    • 枚举基本上命名了一个数字。在我发布的代码中,我将布尔值放入一个可能性列表中,并有意将列表中的索引与枚举表示的数字匹配(Directions.Right == 0)。由于在国际象棋中有许多类型的移动,我建议您创建一个名为 Moves 的类并将您的移动风格逻辑放在那里。然后你可以调用,比如说,Moves.Knight.ForwardRight() 并且棋子向前移动两个,向右移动一个。 Moves.Queen.DownLeft(x) 可以移动皇后 x 个空格。
    • 我为每个持有的棋子都有课程
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多