重写 Delphi 表单构造函数和使用它的 OnCreate 事件是否存在问题?
Delphi 帮助说要么重写表单的构造函数,要么使用 OnCreate 事件。但不要两者都做。这是什么原因呢?我唯一能看到的是,如果继承被排除在后代的构造函数之外,则 TCustomForm.Create 将不会被调用。所以在这种情况下 OnCreate 不会被调用。但如果不排除遗传因素,我就不认为有什么问题。
编辑:我应该添加我的问题的原因。我实际上并不打算在同一堂课中使用两者。但当后代已经在使用 OnCreate 时,我正在考虑重写基类中的构造函数。所以我想知道是否存在某种我没有意识到的冲突。但我的印象是应该没问题。尽管我可能只使用基类中的 OnCreate 来保持一致。
另一个编辑:感谢大家的帮助。因此,如果操作正确的话,使用这两种方法实际上不会破坏任何东西。但这样做的问题是,它使代码难以理解。我想我应该选择一个最佳答案,但每个人似乎都同意。所以我就选那个 首先发布。
Delphi help says either override a form's constructor, or use the OnCreate event. But don't do both. What's the reason for this? The only thing I can see, is if inherited is left out of the constructor in a descendant, TCustomForm.Create won't get called. So OnCreate won't get called in that case. But if inherited isn't left out, I don't see the problem.
edit: I should add the reason for my question. I'm not actually planning to use both in the same class. But I was considering overriding the constructor in a base class, when a descendant is already using OnCreate. So I was wondering if there was some kind of conflict I wasn't aware of. But I'm getting the impression that should be ok. Although I may just use the OnCreate in the base class to keep it consistent.
another edit: Thanks everyone for the help. So it looks like using both methods won't actually break anything, if you do it correctly. But the problem with doing it, is that it makes the code hard to understand. And I guess I'm supposed to pick a best answer, but everyone seems to be in agreement. So I'll just pick the one that was
posted first.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
两个人都会被叫到。不过,这个建议是合理的,因为使用两者会让代码的读者感到困惑。
Both will get called. The advice is sound though since using both is confusing to readers of the code.
考虑到您的编辑,不,使用它们两者没有问题。
只需确保您像这样编写覆盖的构造函数:
另请注意,OnCreate 处理程序将在您添加的 Create 代码之前调用,因此请注意这一点。这很快就会让人感到困惑,这就是手册建议不要这样做的原因。
警告
如果您重写一个类,请不要使用 OnCreate,因为这可能会阻止 OnCreate 事件的用户对此进行操作,只需在重写的构造函数中执行您的操作即可。
规则是,在 TMyForm 的每个实例的创建中需要相同的内容应该进入重写构造函数。
根据使用 TMyForm 的位置创建不同的内容应该进入 OnCreate 处理程序。
如果与附近的其他组件存在任何依赖关系,那么您的代码应始终进入 OnCreate 处理程序。
Considering your edit, no there is no problem in using them both.
Just make sure you write your overriden constructor like so:
Also note that the
OnCreate
handler will be called before your added Create code so be aware of that. This can get confusing fast, that's why the manual recommends against it.Warning
If you override a class do not use OnCreate, because that might block users of the OnCreate event from acting on that, just do your thing in the overriden constructor.
The rule is that stuff that needs to the same in the Create of every instance of TMyForm should go into an override constructor.
Create stuff that can be different depending on where the TMyForm is used should go into the OnCreate Handler.
If there are any dependencies with other components nearby, then your code should always go into the OnCreate handler.
您最终可能会在两个不同的地方放置相同或冲突的代码。我自己几乎总是使用 OnCreate 事件。
You may end up placing identical - or comflicting - code in two different places. I almost always use the OnCreate event myself.
如果有几个地方你可以做任何事情。只需选择一个并坚持下去。仅在合理的情况下才使用其他位置。
主要原因是清晰度。您可以避免一些错误,因为您遵循相同的模式。
If there are several places you can do anything. Just chose one and stick to that. Only use another place if its justified.
The prime reason is clarity. You avoid some mistakes because you are following the same pattern.
我在必要时使用 onCreate 事件 - 我从不喜欢覆盖 TForm 的默认构造函数 - IMO 你总是会在以后的某个时刻遇到复杂和混乱。
处理此问题的其他方法(如果可能的话,我更喜欢这种方法):
向表单添加一个“初始化”方法 - 在创建它之后但在显示它之前调用它。这类似于 COM 对象所发生的情况 - 构造函数没有参数,您可以在 Initialize 调用中完成您的任务。
有时,在表单单元上但在表单类之外使用变量和函数也是合适的——正如 Delphi 本身不断所做的那样。与此方法结合使用时,请考虑使用表单单元的初始化和终结部分 - 尽管要非常小心,特别是对于使用 Owner 属性进行清理的 COM 对象或组件 - 您可能会遇到AV 在关闭清理时出现问题。
I use onCreate event when necessary - I never like to override TForm's default constructor - IMO you'll invariably run into complications and confusion at some point further on.
Other ways of handling this, which I prefer when it's possible:
Add an 'initialize' method to the form - call it after creating it but before showing it. This akin to what happens with COM objects - constructors have no parameters and you do your business in the Initialize call.
Also sometimes it's appropriate to use variables and functions on your form unit but outside the form class - as Delphi itself continually does. In conjuction with this approach, consider using the initialization and finalization sections of your form unit as well - albeit with GREAT CARE, particularly with COM objects or components where you're using the Owner property for clean up - you're likely to run into problems with AV's on shutdown-clean ups.