[英]In delphi 7, is `try … except raise; end;` meaningful at all?
In some Delphi 7 code I am maintaining, I've noticed a lot of instances of the following: 在我维护的一些Delphi 7代码中,我注意到以下很多实例:
with ADOQuery1 do begin
// .. fill out sql.text, etc
try
execSQL;
except
raise;
end;
end;
It seems to me that these try blocks could be removed, since they do nothing. 在我看来,这些尝试块可以被删除,因为它们什么都不做。 However, I am wary of possible subtle side-effects..
但是,我对可能出现的微妙副作用持谨慎态度。
Can anyone think of any instances in which these blocks could actually do anything that wouldn't happen without them there? 任何人都可以想到这些块实际上可以做任何没有它们的情况下会发生的事情吗?
In this context, the raise operation has no effect and should be removed becuase its simply re-raising the exception that the exception block just caught. 在这种情况下,raise操作没有任何效果,应该删除它,因为它只是重新引发异常块刚刚捕获的异常。 raise is typically used to transfer control to the end of the block when no appropriate error handling is available.
raise通常用于在没有适当的错误处理时将控制转移到块的末尾。 In the following we handle the custom exception, but any other exception should be handled elsewhere.
在下面我们处理自定义异常,但任何其他异常应该在别处处理。
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;
Be careful that there is similar looking form without the "raise" that DOES have the side effect of eating/hiding any exceptions. 小心有没有“提高”的类似外观形式,它具有吃/隐藏任何例外的副作用。 practicies by very unscrupulous developers who have hopefully moved on to positions with the competition.
非常肆无忌惮的开发人员的实践,他们希望能够在竞争中占据一席之地。
with ADOQuery1 do begin
// .. fill out sql.text, etc
try
execSQL;
except
// no handler so this just eats any "errors"
end;
Removing the except code in above code snippet will make no difference. 删除上面代码段中的except代码将没有任何区别。 You can (and I believe you should since it is reducing the readability) remove it.
您可以(我相信您应该因为它降低了可读性)将其删除。
Okay, really two questions here. 好的,这里真的有两个问题。
First, it is meaningful: if execSQL throws an exception, it's caught by the try block and forwarded to the except. 首先,它是有意义的:如果execSQL抛出异常,它会被try块捕获并转发到except。 Then it's forwarded on by the raise to the next higher block.
然后它被加注转发到下一个更高的块。
Second, is it useful ? 第二,它有用吗? Probably not.
可能不是。 It almost certainly is the result of one of three things:
它几乎肯定是三件事之一的结果:
execSQL
statment into some other, more meaningful, exception. execSQL
语句中的异常转换为其他更有意义的异常。 I may have answered a bit fast, see at the end... 我可能回答得有点快,最后看到......
Like it is, it is useless for the application . 就像它一样,它对应用程序来说是无用的 。
Period! 期!
Now on the "why" side. 现在关于“为什么”的一面。 It may be to standardize the exceptions handling if there /was/will be/is in other places/ some kind of logging code inserted before the raise:
可能是标准化异常处理,如果/是/将/在其他地方/在加注之前插入某种日志代码:
try
execSQL;
except
// Log Exception..
on E: Exception do
begin
LogTrace(Format('%s: Exception Message[%s]',[methodname, E.Message]));
raise;
end;
end;
or for Cleanup code: 或者用于清理代码:
try
execSQL;
except
//some FreeAndNil..
raise;
end;
Update : There would be 1 case where I would see some use just like it is... 更新 :有一种情况我会看到一些使用就像它...
... to be able to put a Breakpoint on the raise
line, to get a chance to see what's going on in the context on that block of code. ...能够在
raise
线上放置一个断点,以便有机会看到该代码块上下文中发生了什么。
This code does nothing, other than to allow the original programmer to place a breakpoint on the 'Raise' and to see the exception closer in the source to its possible cause. 除了允许原始程序员在'Raise'上放置断点并在源中看到更接近其可能原因的异常之外,此代码不执行任何操作。 In that sense it a perfectly reasonable debugging technique.
从这个意义上说,这是一种非常合理的调试技
Actually, I should posted this as comment to François's answers, but I don't know is it possible to insert formatted code there :( So I'm posting this as answer. 实际上,我应该将此作为对François的答案的评论发布,但我不知道是否可以在那里插入格式化的代码:(所以我将其作为答案发布。
2mghie: 2mghie:
The second one is completely unidiomatic, one would use finally instead.
第二个是完全单一的,最后会用到。
No, "finally" will cleanup object always. 不,“终于”将永远清理对象。 "Except" - only on exception.
“除了” - 仅限于例外情况。 Consider the case of function, which creates, fills and return an object:
考虑函数的情况,它创建,填充和返回一个对象:
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;
If you put "finally" there - function will return nil always. 如果你把“finally”放在那里 - 函数将始终返回nil。 If you omit "try" block at all - there will be resources leak in case of exception in "...".
如果省略“try”块 - 在“...”中出现异常时会有资源泄漏。
PS Of course, you can use "finally" and check ExceptObj, but... isn't that ugly? PS当然,你可以使用“finally”并检查ExceptObj,但是......不是那么难看吗?
The title contains quite a broad question, while its explanation gives a more specific example. 标题包含相当广泛的问题,而其解释给出了一个更具体的例子。 So, my answering to the question as how it proceeds from the example, can doubtly add anything useful to what has already been said here.
所以,我回答这个例子的问题,可以肯定地增加了对这里已经说过的内容有用的东西。
But, maybe Blorgbeard indeed wants to know whether it is at all meaningful to try ... except raise; end
但是, 也许 Blorgbeard确实想知道它是否在所有有意义的
try ... except raise; end
try ... except raise; end
. try ... except raise; end
。 In Delphi 7, if I recollect correctly, Exit
would trigger the finally
part of a try-finally
block (as if it were some sort of exception). 在Delphi 7中,如果我正确地重新收集,
Exit
将触发try-finally
块的finally
部分(就好像它是某种异常)。 Someone might consider such behaviour inappropriate for their task, and using the construction in question is quite a workaround. 有人可能认为这种行为不适合他们的任务,并且使用相关结构是一种解决方法。
Only it would still be strange to use a single raise;
只使用一次
raise;
仍然是奇怪的raise;
there, but then we should have talked about usefulness rather than meaningfulness , as Charlie has neatly observed. 在那里,但我们应该谈论有用性而不是有意义 ,正如查理巧妙地观察到的那样。
This code does nothing except re-raising an exception that will allready be raised without this try except block. 除了重新引发一个异常,除了块之外没有这个尝试,这个代码什么都不做。 You can safely remove it.
你可以安全地删除它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.