Delphi 2009 处理 with
有人知道 Delphi 2009 对“with”的处理有什么不同吗?
我昨天解决了一个问题,只是通过将“with”解构为完整引用,如“with Datamodule、Dataset、MainForm”。 Delphi 2006 及更早版本对数据集应用“关闭”。 Delphi 2009 对 MainForm 应用了“关闭”并退出了应用程序!
Anybody know what is different about Delphi 2009's handling of "with"?
I fixed a problem yesterday just by deconstructing "with" to full references, as in "with Datamodule, Dataset, MainForm". Delphi 2006 and earlier applied "Close" to the Dataset. Delphi 2009 applied "Close" to the MainForm and exited the application!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
什么也没有变。 你之前的观察是错误的。
with
语句中提到的对象被视为“从右到左”,因此在您的示例中,将首先搜索MainForm
,然后搜索Dataset
,然后是数据模块。 一直都是这样。 这与您编写的内容相同:继续查看 Delphi 2006 文档; 应该有一个名为声明和语句的部分,在该部分下您可以找到结构化语句,包括With语句部分。
帮自己一个忙,不要使用
with
。 它在调试和维护期间都会造成无穷无尽的麻烦,甚至可以由前一天编写代码的人来执行维护。Nothing has changed. Your previous observation was wrong. The objects mentioned in a
with
statement are considered "right to left," so in your example,MainForm
would be searched first, thenDataset
, and thenDatamodule
. That's how it's always been. It's the same as if you'd written this:Go ahead and check the Delphi 2006 documentation; there should be a section named Declarations and statements, under which you'll find Structured statements, including the section on With statements.
Do yourself a favor and don't use
with
. It causes no end of trouble both during debugging and during maintenance, where maintenance could even be performed by the person who wrote the code just the day before.With
是邪恶的。 我不知道我需要说多少次,但显然我们还没有到那一步。With 只能“安全”地与永远不会改变的对象一起使用。 如果您将其应用于您在自己的项目中定义的对象,那么所有的赌注都会被取消,我敢说您应该只使用“if Random(50)<25”部分来执行您的代码,它至少被记录为执行奇怪。
问题是,一旦你开始弄乱一个对象,引入新的方法或属性,或者重命名旧的方法或属性,所有使用这些方法的现有
with
语句都有可能改变含义。 并且不在“警告:调用不明确的方法”中进行更改。 该代码将只执行与之前不同的操作。 没有告诉你这件事。例如,假设您有这样的情况:
那么您期望发生什么? 嗯,关闭文件是很自然的事情,所以我希望文件被关闭。 我们进一步假设该文件变量包含一个 TSomeOddFile 类型的对象,该对象未定义 Close 方法,而是定义 CloseFile 方法。 上面的 With 语句将关闭连接。
一切都很好,它已记录在案,没有人编写这段代码认为该文件将被关闭,毕竟,该方法被命名为该对象的 CloseFile,这只是我的假设是错误的,而且我不参与该项目。 然而。
然后有人修复了这个问题,将 CloseFile 重命名为 Close。 上面的代码将默默地开始关闭文件而不是连接。 没有警告,没有错误,编译就像更改方法名称之前一样好。 运行得一样好^h^h^h,不用等,它不会。
所以,是的,
with
会咬你一口**。With
is evil. I don't know how many times I need to say this, but apparently we're not there yet.With can only "safely" be used with objects that are never going to change. If you apply it to objects you define in your own project, all bets are off and I'd daresay you should rather just use "if Random(50)<25" parts to execute your code, it's at least documented to executed oddly.
The problem is that once you start messing with an object, introducing new methods or properties, or renaming old ones, all existing
with
-statements that use those methods has the potential to change meaning. And not in the "Warning: Call to ambiguous method" change either. The code will just do something other than it did previously. Without telling you about it.For instance, let's assume you have this:
then what do you expect to happen? Well, it's natural to close a file, so I would expect the file to be closed. Let's further assume that this file variable holds a object of type TSomeOddFile that doesn't define a Close method, but rather a CloseFile method. The above With-statement will then close the connection instead.
All good, it's documented, nobody wrote this piece of code thinking that the file would be closed, after all, the method is named CloseFile for that object, it's just my assumption that is wrong and I don't work on the project. Yet.
And then someone fixes that, renaming CloseFile to Close. The above code will silently start closing the file instead of the connection. No warning, no error, compiles just as fine as before you changed the method name. Runs just as fine^h^h^h, no wait, it won't.
So yeah,
with
will bite you in the a**.将
与 A,B,C,D
一起使用是不好的做法,因为对其他单位的更改可能会突然导致您的代码停止按预期工作。 请参阅此处了解更多信息,或此处(搜索“使用关键字”)。
Using
with A,B,C,D
is bad practice since changes to other units can suddenly cause your code to stop working as expected. See here for more information, or here (search for"with keyword"
).编译器通常非常可靠,因此在您真正排除其他所有内容之前,我不会假设存在错误或更改。 我很快就能想到一些事情:
1)看看你是否使用了重载函数或运算符。 由于 STRING(以及其他几种类型)的定义发生了变化,因此可以选择不同的变体,因为签名实际上发生了变化。
2) 也可能是某些包含的单元现在定义了一个已使用的标识符,并且优先于在不同单元中公开的标识符。
如果没有,请开始在最小示例中隔离代码,使用尽可能少的单元。 一步一步地做,因为诀窍在于行为改变时最后的改变是什么。
在这里发布该内容(或 URL),看到它总是很有趣。
The compiler is usually quite solid, so I wouldn't assume a bug or change before you really excluded everything else. Some things I can quickly think of:
1) Look if you use overloaded functions or operators. Since the definition of STRING (and several other types) changed, a different variant can be chosen, because the signature effectively changes.
2) it can also be that some included unit now defines an identifier that is already used, and taking precedence over the one exposed in an different unit.
If not, start isolating the code in a minimal example, using as little units as possible. Do it step by step, since the trick is what the last change was when the behaviour changed.
Post that (or an URL) here, it is always interesting to see.
With..do 需要小心使用。 否则,将是无限的头痛之源……我同意罗布·肯尼迪和其他人的观点。
正如 Craig Stuntz (在其他关于with..do的帖子)和Lasse V. Karlsen上面说过,with..do可以创造很多陷阱。
With..do is to be used with care. Otherwise, is a infinite source of headaches.... I agree with Rob Kennedy and others.
As Craig Stuntz (in other post about with..do) and Lasse V. Karlsen above said, with..do can create a lot of traps.