2016-05-14 3 views
0

Delphi с командой не работает правильно?Delphi с командой изменения свойств последнего объекта

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

Я пытался использовать этот код, указанный выше в супер простой программы, но кнопка изменяет только заголовок свойство Метка2, НЕ Label1. Когда код выглядит так:

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

Он правильно изменяет свойства метки 1. Как мне изменить код, чтобы он изменил свойства обоих объектов?

+4

Существует очень легкое решение для этого, а именно: когда вы понимаете, что ваши пальцы набрали «с», быстро ударяйте назад 4 раза и начинайте все заново. –

+1

'with' - общий источник ошибок программирования. –

+2

Какую документацию вы прочитали, предложив, чтобы один оператор присваивания изменял свойства нескольких объектов? Мы должны выяснить, чтобы мы никогда не рекомендовали этот источник никому другому. –

ответ

4

Из документации Delphi:

При наличии нескольких объектов или записи появляются после того, как с, весь оператор рассматривается как ряд вложен с заявлениями. Таким образом,

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

эквивалентно

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

В этом случае каждая ссылка на переменную или метод имя в заявлении интерпретируется, если это возможно, в качестве члена objn; в противном случае оно интерпретируется, если это возможно, как член objn1; и так далее. Это же правило применяется и к интерпретации самих objs, так что, например, если objn является членом обоих obj1 и obj2, он интерпретируется как obj2.objn.

Как вы обнаружили, это только одно место, где с не работает.

4

Непосредственная:

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

Просто некоторые советуют: Не используйте with!

В своем первом коды with для LABEL2 ловит объем и скрывает Caption свойства Label1. В общем, если вам нужны два задания, вам нужно написать два назначения. Вы можете использовать цикл в зависимости от ситуации, но этот пример проще всего сделать, как показано выше.

Если у вас есть последняя версия Delphi вы можете написать что-то вроде этого:

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

ИМХО, это еще хуже - по крайней мере, для этого случая.

Смежные вопросы