有人知道Delphi 2009在处理"with"时有什么不同吗?
昨天我通过将"with"拆解为完整的引用,例如"with Datamodule, Dataset, MainForm",成功解决了一个问题。 Delphi 2006及更早版本会将"Close"应用于Dataset,而Delphi 2009会将"Close"应用于MainForm并退出应用程序!
有人知道Delphi 2009在处理"with"时有什么不同吗?
昨天我通过将"with"拆解为完整的引用,例如"with Datamodule, Dataset, MainForm",成功解决了一个问题。 Delphi 2006及更早版本会将"Close"应用于Dataset,而Delphi 2009会将"Close"应用于MainForm并退出应用程序!
没有任何改变。你之前的观察是错误的。在with
语句中提到的对象被认为是“从右到左”的,所以在你的例子中,首先会搜索MainForm
,然后是Dataset
,最后是Datamodule
。这一直都是这样的。这与你写下以下代码的效果相同:
with Datamodule do
with Dataset do
with MainForm do begin
Close;
end;
可以查看Delphi 2006文档;应该有一个名为声明和语句的部分,在其中您会找到关于结构化语句的内容,其中包括With语句的部分。
建议您不要使用with
。它在调试期间和维护期间都会引起很多问题,维护甚至可能是由编写代码的人在前一天执行的。
var dset: TDataset; dset := DBComponent.DataSource.Dataset; dset.foo; dset.bar;
- Rob KennedyWith
很危险。我不知道我需要说多少次,但显然我们还没有意识到这一点。
With
只能“安全”地用于永远不会改变的对象。如果将其应用于您在自己的项目中定义的对象,则所有投注都无效,我敢说您应该只使用“if Random(50)<25”部分来执行代码,至少可以记录下奇怪的执行情况。
问题在于,一旦开始操作对象,引入新的方法或属性,或者重命名旧方法,所有现有的with
语句使用那些方法都有可能改变含义。并且不是“警告:调用模糊方法”的更改。代码将只是执行先前不同的其他操作,而没有告诉您。
例如,假设您有以下内容:
with connection, file do
begin
Close;
end;
那么你希望会发生什么?关闭文件是再自然不过的事情了,所以我期望文件会被关闭。让我们进一步假设,这个文件变量保存的是TSomeOddFile类型的对象,该对象没有定义Close方法,而是定义了CloseFile方法。那么上面的With语句将会关闭连接。
没问题,这已经有文档说明了。毕竟,没有人写这段代码时认为文件会被关闭,毕竟该对象的方法名就是CloseFile,只是我的假设是错误的,而我也不在这个项目中工作。但未来可能会加入该项目。
然后有人修复了这个问题,将CloseFile重命名为Close。上面的代码将悄无声息地开始关闭文件,而不是连接。没有警告,没有错误,编译后和之前一样运行良好。实际上并没有运行良好,等等,它根本不会运行良好。
所以,with
语句会让你吃大亏。
With..do 需要小心使用,否则会成为无尽的头痛之源... 我同意 Rob Kennedy 和其他人的观点。
正如 Craig Stuntz(关于 with..do 的其他帖子)和 Lasse V. Karlsen 上面所说,with..do 可能会造成许多陷阱。