什么时候提出例外?

WeG*_*ars 1 delphi

我认为这是“最佳实践”类别的问题:

我有一个自定义控件-一种可容纳一些面板的网格。面板之一是当前活动面板(最后一个单击)。

TMyGrid = class (TSomeKindOfGrid)
  published
    property CurrentPanel: TPanel read getCurPanel write setCurPanel;
end;
Run Code Online (Sandbox Code Playgroud)

我的问题是:如果在某个时候有人要求CurrentPanel且网格为空,应该getCurPanel返回NIL还是引发异常?

  • 如果getCurPanel返回NIL,则我必须在每次/每次致电时都要检查NIL CurrentPanel。呼叫者也有可能忘记检查NIL。好吧,因为它将尝试访问NIL对象,所以不会发生任何“不良”情况。该程序将很好地崩溃。我得到了堆栈跟踪。
  • 如果我在中提出了异常getCurPanel,我只会在一个地方进行检查(是的,我很懒)。

Rud*_*uis 5

如果返回nil,则使用户有机会检查返回值并跳过他或她打算在当前面板中执行的任何操作:

panel := XYZ.currentPanel;
if Assigned(panel) and (panel.Index = 17) then
begin
Run Code Online (Sandbox Code Playgroud)

上面的代码运行没有任何不必要的中断。

如果您立即提出异常,则不会给用户提供任何机会来发现是否存在当前面板。换句话说,提出例外将为时过早。与上面相同的代码将崩溃。

但是我承认这是我的个人喜好(也许是很多,但不是全部)。这是一个见解。


但是除了返回a之外nil,您还可以公开一个PanelCount属性。如果人们需要检查类似的东西,那么如果计数为零,那么如果有人试图访问面板,您也可以提出建议。那时还不成熟。


如您所见,有几种方法可以做到这一点。

注意

正如SilverWarrior在注释中正确注意到的那样,它currentPanel是已发布的属性,最终将出现在“对象检查器”中。那可以处理返回的属性nil,但不一定处理引发异常的属性。

所以:最好的建议是退货nil

  • 在这种情况下,OP不应引发异常还有另一个原因。如果检查OP提供的代码,则可以看到声明的他的属性已发布。这意味着他很可能打算在设计时在对象检查器中看到此属性。因此,尽管使对象检查器正确处理了结果为零的属性,但我仍然怀疑它是否可以处理任何引发的异常。实际上,通过在已发布属性中添加异常,您甚至可能完全崩溃Object Inspector。 (2认同)