Why should I not use “with” in Delphi?我听说很多程序员,尤其是Delphi程序员都对'with'的使用表示反感。 我认为它可以使程序运行更快(仅对父对象有一个引用),并且如果明智地使用它,则更容易阅读代码(少于十几行代码且没有嵌套)。 这里是一个例子:
我喜欢使用 使用with的一个烦恼是调试器无法处理它。因此,这使调试更加困难。 更大的问题是,阅读代码不太容易。尤其是在with语句更长的情况下。
将调用哪个Form的CallThisFunction?自我(TMyForm)还是OtherForm?不检查OtherForm是否具有CallThisFunction方法就无法知道。 最大的问题是,您甚至可以在不知道的情况下轻松实现错误。如果TMyForm和OtherForm都具有CallThisFunction却是私有的,该怎么办。您可能希望/希望调用OtherForm.CallThisFunction,但实际上不是。如果您不使用with,编译器会警告您,但现在不使用。 在with中使用多个对象会使问题成倍增加。参见http://blog.marcocantu.com/blog/with_harmful.html 在这种情况下,我更喜欢VB语法,因为在这里,您需要在with块内的成员前面加上
但是实际上, 如果将
您不需要声明变量" x"。它将由编译器创建。使用哪个函数写起来很快,没有混乱。 " with"不太可能使代码运行更快,编译器更有可能将其编译为相同的可执行代码。 人们不喜欢" with"的主要原因是,它可能引起名称空间范围和优先级的混淆。 在某些情况下,这是一个实际问题,而在某些情况下,这不是问题(非问题案例将在问题中描述为"明智使用")。 由于可能会造成混淆,即使在可能没有混淆的情况下,一些开发人员也选择完全避免使用" with"。这似乎是教条,但是可以争论的是,随着代码的更改和增长,即使在将代码修改到一定程度以至于使" with"引起混淆的情况下," with"的使用也可能会保留,因此最好不要首先介绍其用法。 事实上:
和
将生成完全相同的汇编代码。 如果 事实上:
由编译器以伪代码进行编码:
那么 我个人有时会在代码中使用,但是我几乎每次生成的asm都要检查一次,以确保它能完成应有的工作。并不是每个人都有能力或有时间去做,所以恕我直言,局部变量是with的很好选择。 我真的不喜欢这样的代码:
使用以下命令仍然可读性强:
甚至
但是如果内部循环很大,则使用局部变量确实有意义:
此代码不会比 顺便说一句,它将使调试更加容易:您可以放置??一个断点,然后将鼠标直接指向 这种争论也经常发生在Javascript中。 基本上,有了语法,很难一眼就知道要调用哪个Left / Top / etc属性/方法。您可能有一个名为Left的局部变量和一个属性(从那时起已经有一段时间了。我已经完成了delphi,如果名称错误,对不起),它叫做Left,甚至一个叫做Left的函数。任何不熟悉ARect结构的人都可能会非常迷路。 您保存的键入内容会失去可读性。 考虑使with语句中的代码成为您所引用对象的方法。 主要是维护问题。 从语言的angular来看,WITH的想法是合理的,并且合理地使用它的理由是,保持代码的说法更合理,更小,更清晰。但是,问题在于,大多数商业代码将在其生命周期内由几个不同的人维护,而当编写时,它最初是一个小的,易于解析的构造,但是随着时间的流逝,它们很容易转变为笨重的大型结构,而WITH的范围并不大。维护人员可以轻松解析。这自然会产生错误,并且很难找到错误。 例如,说我们有一个小的函数foo,其中包含三到四行代码,这些代码被包装在WITH块中,那么实际上没有问题。但是,几年后,在几个程序员的带领下,此功能可能扩展为仍然封装在WITH中的40或50行代码。现在这很脆弱,并且已经很容易引入错误,尤其是如果维护人员开始引入额外的嵌入式WITH块的情况下。 没有其他好处-代码应该完全相同地解析并以相同的速度运行(我在D6内的3D渲染紧密循环中对此进行了一些实验,我发现没有区别)。调试器无法处理它也是一个问题-但是应该早就解决这个问题,值得一试,是否有任何好处。不幸的是没有。 我不喜欢它,因为它使调试麻烦。您不能仅通过用鼠标悬停在变量上来读取变量等的值。 您可以将其与语句结合使用,因此您最终会得到
如果您认为调试器与一个人混淆,那么我看不到有人可以确定 在工作中,我们给出了从现有的Win 32代码库中删除Withs的要点,因为维护使用它们的代码需要付出额外的精力。我在以前的工作中发现了几个错误,其中一个名为BusinessComponent的局部变量被位于对象的具有相同类型的已发布属性BusinessComponent的With开头块遮盖了。编译器选择使用已发布的属性,以及使用崩溃的局部变量的代码。 我看过类似 的代码 用a,b,c,d来做(除非它们是更长的名字,在这里只是简称) 试图找到xyz的来源可能是一件非常痛苦的事情。如果是c,我会尽快将其写为 i:= c.xyz; 您认为理解这很琐碎,但不是在一个800行长的函数中,该函数在一开始就使用了with!
不一定-您的编译器/解释器在优化代码方面通常比您更擅长。 我认为这让我说"糟糕!"因为它很懒惰-当我阅读代码(尤其是其他人的代码)时,我喜欢看到显式的代码。因此,我什至会在Java中编写" this.field"而不是" field"。 它允许不称职或邪恶的程序员编写无法阅读的代码。因此,仅当您既不称职也不邪恶时才使用此功能。 只要保持简单并避免歧义,它没有任何问题。 据我所知,它并没有加快任何速度-纯粹是语法糖。 我们最近在我们的Delphi编码标准中禁止了它。 优点经常超过缺点。 那是由于误用而引入的错误。这些并不能证明节省时间来编写或执行代码。 是的,使用with可以(缓慢地)更快地执行代码。 在下面,仅对foo进行一次评估:
但是,这里它被评估了三遍:
对于Delphi 2005,with-do语句中存在硬错误-评估指针丢失并向上移动指针。必须使用局部变量,而不是直接使用对象类型。 |