首页 / 知识
为什么我不应该在Delphi中使用” with”?
2023-04-15 21:04:00

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语句中存在硬错误-评估指针丢失并向上移动指针。必须使用局部变量,而不是直接使用对象类型。 |
最新内容
相关内容
linux无效对象的命令?
linux无效对象的命令?,软件,系统,单位,网络,管理,术语,检测,电脑,环境,风险,linux疑问:普通用户的ifconfig命令无法执行,如何解决?建议这个操pythonPandas Series对象有哪些属
pythonPandas Series对象有哪些属性?,工具,数据,数字,分析,培训,属性,数据类型,数组,对象,索引,想必大家都知道pandas,它是基于Numpy的一种工具python是面向对象还是面向过程的
python是面向对象还是面向过程的,数据,代码,基础,形态,培训,术语,设计,对象,过程,语言,Python虽然是解释型语言,但从设计之初就已经是一门面向Python怎么处理程序运行中的问题?
Python怎么处理程序运行中的问题?,代码,培训,问题,句子,程序,上述,类型,操作,整数,发生,Python程序在运转时出现的问题会导致程序溃散,这种问题实现Python对象的持久化存储
实现Python对象的持久化存储,数据,对象,系统,函数,培训,标准,环境,管理,参数,文件,Python中有个序列化过程叫作pickle,它能够实现任意对象与文python之访问对象的元数据
python之访问对象的元数据,数据,异常,培训,属性,模块,对象,类型,定义,文档,实例,当你对一个你构造的对象使用dir()时,可能会发现列表中的很多python之执行对象
python之执行对象,代码,数据,信息,概念,培训,通用,对象,属性,方法,赋值,有时候我们会碰到这样的需求,需要执行对象的某个方法,或是需要对对象的Python之数据库游标对象详解
Python之数据库游标对象详解,软件,代码,一致,培训,数据库,游标,对象,方法,事务,操作,常用数据库:MySQL、Oracle、SQLite但是包嵌入到Python中Python 中的一切皆对象
Python 中的一切皆对象,代码,数字,包装,培训,对象,函数,赋值,血统,字符串,变量,在Python中,OOP是完全不是必须的,在初学阶段也不需要使用类,利用Python类和对象
Python类和对象,代码,培训,对象,实例,定义,关键字,函数,问题,顶层,全名,刚接触python中的类和对象,我也和大多数小伙伴一样迷茫,不知道它和我所Python中JSON 对象有哪些特点?
Python中JSON 对象有哪些特点?,名称,信息,代码,培训,数据,观察,对象,嵌套,数组,特点,JSON对象的结构是什么样子呢?上面代码中的obj就是一个JSPython中的对象
Python中的对象,数据,连续,代码,培训,概念,对象,内存,类型,初始化,静态,Python中一切皆是对象。————GuidovanRossum(1989)这句话只要你学