代码之家  ›  专栏  ›  技术社区  ›  Blorgbeard

在delphi 7中,是“try…”除了raise;结束;`有意义吗?

  •  7
  • Blorgbeard  · 技术社区  · 15 年前

    在我维护的一些Delphi 7代码中,我注意到以下许多实例:

    with ADOQuery1 do begin
      // .. fill out sql.text, etc
      try
        execSQL;
      except
        raise;
      end;
    end;
    

    8 回复  |  直到 15 年前
        1
  •  10
  •   MikeJ    15 年前

    在这种情况下,raise操作没有效果,应该删除,因为它只是重新引发异常块刚刚捕获的异常。raise通常用于在没有适当的错误处理可用时将控制转移到块的末尾。在下文中,我们将处理自定义异常,但任何其他异常都应在其他地方处理。

    try
      someOperation;
    except
      on e: ECustomException do
        SomeCustomHandelr;
      else
         begin
           // the raise is only useful to rethrow the exception to an encompasing 
           // handler.  In this case after I have called my logger code. as Rob
           // mentioned this can be omitted if you arent handling anything because
           // the compiler will simply jump you to the next block if there is no
           // else.
           LogUnexpectedException('some operation failed',e);
           raise;
         end;
    end;
    

    请注意,有一种外观相似的形状,但没有“raise”,它确实会产生吃/藏任何异常的副作用。非常不择手段的开发商的做法,他们希望能够在竞争中占据一席之地。

    with ADOQuery1 do begin  
      // .. fill out sql.text, etc  
      try    
        execSQL; 
      except
        // no handler so this just eats any "errors"    
      end;
    
        2
  •  6
  •   Hemant    15 年前

    删除上述代码段中的except代码不会有任何区别。你可以(而且我相信你) 应该 因为它降低了可读性)请删除它。

        3
  •  2
  •   Charlie Martin    15 年前

    首先是它 有意义:如果execSQL抛出异常,则try块将捕获该异常并将其转发到except。然后,它被提升转发到下一个更高的区块。

    有用的 ? 可能不会。这几乎可以肯定是三件事之一的结果:

    1. 有人打算回来,把 execSQL
    2. 一些新来的人没有意识到他们写的东西与让外部环境担心异常是同构的,所以他们认为 转发它。
        4
  •  2
  •   Francesca    15 年前

    我可能回答得有点快,看最后。。。
    就像它一样,它对应用程序是无用的 .
    时期

    现在谈谈“为什么”。如果在raise之前插入了/曾经/将会/正在其他地方/某种类型的日志代码,则可能需要标准化异常处理:

      try
        execSQL;
      except
        // Log Exception..
        on E: Exception do
        begin
          LogTrace(Format('%s: Exception Message[%s]',[methodname, E.Message]));
          raise;
        end;
      end;
    

    或用于清除代码:

      try
        execSQL;
      except
        //some FreeAndNil..
        raise;
      end;
    

    使现代化
    ... 能够在 raise 第行,以便有机会看到在该代码块的上下文中发生了什么。

        5
  •  2
  •   Brian Frost    15 年前

    这段代码除了允许原始程序员在“Raise”上放置一个断点,并在源代码中更近距离地查看异常的可能原因之外,什么都不做。从这个意义上说,它是一种完全合理的调试技术。

        6
  •  1
  •   Alex    15 年前

    事实上,我应该将此作为对Fran§ois答案的评论发布,但我不知道是否可以在此处插入格式化代码:(所以我将此作为答案发布)。

    2mghie:

    function CreateObj: TSomeObj;
    begin
      Result := TSomeObj.Create;
      try
        ... // do something with Result: load data, fill props, etc.
      except
        FreeAndNil(Result); // oops: bad things happened. Free object to avoid leak.
        raise;
      end;
    end;
    

    如果您将“finally”放在那里,函数将始终返回nil。如果您完全忽略了“try”块,那么在“…”中出现异常时将出现资源泄漏。

        7
  •  0
  •   Andy M Andy M    15 年前

    标题包含了一个相当广泛的问题,而其解释给出了一个更具体的例子。因此,我对这个问题的回答,以及它是如何从这个例子开始的,无疑可以为这里已经说过的话添加任何有用的东西。

    但是 大概 Blorgbeard确实想知道它是否是 完全 有意义 try ... except raise; end . 在Delphi 7中,如果我没记错的话, Exit 会触发 finally 一部分 try-finally 块(好像它是某种例外)。有些人可能会认为这样的行为不适合他们的任务,并且使用所讨论的结构是一个很好的解决办法。

    只不过使用一个单独的 raise; 有用性 而不是 意义

        8
  •  0
  •   Stephane Wierzbicki    15 年前

    这段代码除了重新引发一个异常之外什么都不做,该异常将在没有try-except块的情况下引发。您可以安全地将其移除。