为什么要检查对象方法中的Assigned(self)?

时间:2009-06-24 20:39:46

标签: delphi delphi-7

我正在查看一些代码(Delphi 7),以下检查位于特定对象的每个方法调用的顶部:

if not Assigned(self) then
  raise Exception.CreateRes(@sAbstractError);

  { Real code for this method}

我想这会阻止我尝试在空对象指针上调用方法。但是,一旦我尝试访问该情况下的成员数据,我会得到一个例外,对吗?

这是我以前从未见过的某种标准吗?有问题的对象来自TPersistent。

6 个答案:

答案 0 :(得分:10)

抱怨nil指针的明显错误比没有说明它是如何发生的访问冲突要好。

答案 1 :(得分:8)

您可以在空指针上调用实例方法,尽管它不是您想要刻意做的事情。当发生这种情况时,执行继续非常愉快,直到它需要访问实例数据,然后一切都响彻。

在这种情况下,检查nil会在程序的顶部提醒您,以便您可以执行不同的操作,例如记录堆栈跟踪。或者你可以在加注线上设置一个断点,这样你就可以潜入并看看发生了什么。

是的,如果我有一个特定的错误,我试图追踪使用零参考的地方,这是我可能会做的事情。

经常这样做会让我觉得有点腥味。

答案 2 :(得分:4)

存在访问冲突的情况,可能导致代码在Self为零的内存中运行。一些程序员,而不是解决真正的问题,试图绕过使用这样的断言,以防止各种腐败。我会很好地检查Exception是否会在运行时提升,如果是这样的话 - 你手边有错误的代码。

您可以阅读以下有关该主题的文章:When Self in Nil... You Know You are in Trouble

另一种可能性与事件有关,您可以在这里阅读更多内容,并提供大量此类测试的示例以及相应的解释:Multicast Events - Part 2

答案 3 :(得分:3)

这是一个绝对会导致崩溃的场合(即“从地址0x00000000读取”等操作系统异常)。抛出一个语言异常只是多余的(并且滥用EAbstractError不会使它变得更好)。

在不安全的语言中检查有效的输入参数不是一项可行的任务,因为您永远无法获得确定性,因此您对无效参数的处理永远不会一致。 (为什么在传递nil指针时抛出异常,而不是0x00000001,这同样无效?)。有关此问题的更多技术讨论,请阅读Larry Osterman关于why not to check for valid pointers的博客。

应该注意一个例外:在Delphi中,可以在nil指针上调用Free方法,这当然需要进行这种检查。

答案 4 :(得分:1)

然后总是有可能在使用nil Self运行时代码不会崩溃。示例 - 如果它未访问所有者对象的任何字段。在这种情况下,此测试将捕获否则将无法检测到的问题。

尽管如此,这仍然将防御性节目推向了极致。我从来没有(好吧,几乎从来没有 - 只有当我在狩猎wabbits ...错误...挤压臭虫时)这样做。

答案 5 :(得分:1)

似乎该方法的初衷是它成为一种抽象方法。