【问题标题】:Delphi with command only changing properties of last objectDelphi 仅使用命令更改最后一个对象的属性
【发布时间】:2016-09-10 23:15:16
【问题描述】:

Delphi with 命令不能正常工作?

procedure TForm1.Button1Click(Sender: TObject);
begin
  With Label1, Label2 do
  begin
    caption := 'Hello'
  end;
end;

我尝试在一个超级简单的程序中使用上面的这段代码,但按钮只更改了 Label2 的标题属性,而不是 label1。当代码如下所示:

procedure TForm1.Button1Click(Sender: TObject);
begin
  With Label1 do
  begin
    caption := 'Hello'
  end;
end;

它正确地改变了 Label1 的属性。我需要如何更改代码才能更改两个对象的属性?

【问题讨论】:

  • 有一个非常简单的解决方法,那就是:当你意识到你的手指已经输入了with,快速按退格键 4 次并重新开始。
  • with 是编程错误的常见来源。
  • 您阅读过哪些文档表明单个赋值语句会修改多个对象的属性?我们必须查明真相,以确保永远不会向其他人推荐该来源。
  • 不要误以为with 提供了一种“优雅”的编程风格。相反,它提供了你不想看到的噩梦。

标签: delphi with-statement


【解决方案1】:

来自 Delphi 文档:

当多个对象或记录出现在 with 之后时,整个语句被视为一系列嵌套的 with 语句。于是

 with obj1, obj2, ..., objn do statement 

等价于

 with obj1 do
   with obj2 do
     ...
     with objn do
       // statement

在这种情况下,如果可能,语句中的每个变量引用或方法名称都被解释为 objn 的成员;否则,如果可能,将其解释为 objn1 的成员;等等。同样的规则也适用于解释 obj 本身,例如,如果 objn 是 obj1 和 obj2 的成员,则它被解释为 obj2.objn。

正如您所发现的,这只是 with 不起作用的一个地方。

【讨论】:

    【解决方案2】:

    直截了当:

    Label1.Caption := 'Hello';
    Label2.Caption := 'Hello';
    

    只是一些建议:不要使用with

    在您的第一个代码中,Label2with 捕获范围并隐藏 Label1Caption 属性。一般来说,如果你想要两个作业,你必须写两个作业。您可能会根据情况使用循环,但如上所示,此示例最简单。

    如果你有最新的 Delphi 版本,你可以这样写:

    var
      lbl: TLabel;
    begin
      for lbl in TArray<TLabel>.Create(Label1, Label2) do
        lbl.Caption := 'Hello';
    end;
    

    恕我直言,情况更糟 - 至少在这种情况下。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-31
      • 1970-01-01
      • 1970-01-01
      • 2017-06-29
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多