Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[35.173.48.18] |
|
Сообщ.
#1
,
|
|
|
In-place создание массива из констант
Этот метод мне подсказал, кажется, leo, за что ему респект. Задача: Иногда бывает нужно сделать перебор ряда однотипных переменных. Самый распространенный пример - массовое управление группами контролов Button1.Enabled := False; Button3.Enabled := False; Button5.Enabled := False; Лично мой взор неуемного оптимизатора сия конструкция оскорбляет, но на первый взгляд от нее никуда не деться - разве что чере временный массив, но и его придется заполнять по одному. Конструкция [item1, item2, ...] работает только в параметрах подпрограмм - ну а создавать отдельную процедуру для одного действия тоже не хочется. К счастью, есть и другой, хитрый способ получить переменную дин. массива, а именно: <dyn_array_type>.Create(item1, item2, ...) Для нашего случая: var btn: TButton; ... for btn in TArray<TButton>.Create(Button2, Button6, Button7) do btn.Enabled := False; либо получаем для неоднократного последующего применения var i: Integer; BtnGroup1: TArray<TButton>; ... BtnGroup1 := TArray<TButton>.Create(Button2, Button6, Button7); ... for i := Low(BtnGroup1) to High(BtnGroup1) do BtnGroup1[i].Enabled := False; А можно и для разношерстных контролов var comp: TControl; ... for comp in TArray<TControl>.Create(Button2, Button6, CheckBox3) do comp.Enabled := False; Работает и без generics, но тип дин. массива обязательно должен быть предварительно объявлен: type TArrayButton = array of TButton; var btn: TButton; ... for btn in TArrayButton.Create(Button1, Button2) do btn.Enabled := False; |
Сообщ.
#2
,
|
|
|
Цитата стесняюсь спросить, а что тут оптимизировано? Лично мой взор неуемного оптимизатора |
Сообщ.
#3
,
|
|
|
SPM, куча однотипных действий выполняется не копипастой, а циклом, как и положено однотипным действиям. Оптимизация скорее на уровне исходника, чем машинного кода.
Добавлено Хорошо пригодится в случае, когда, например, надо управлять доступностью групп контролов на основе уровня юзера. |
Сообщ.
#4
,
|
|
|
Цитата Fr0sT @ Работает и без generics, но тип дин. массива обязательно должен быть предварительно объявлен Можно же использовать Open array parameters... |
Сообщ.
#5
,
|
|
|
Цитата Filka @ Можно же использовать Open array parameters... Как оно применимо к данной ситуации? |
Сообщ.
#6
,
|
|
|
Например, так:
procedure SetEnabledBtn(const BtnArr: array of TButton; Value: Boolean); var I: Integer; begin for I := Low(BtnArr) to High(BtnArr) do BtnArr[I].Enabled := Value; end; procedure TForm1.Button1Click(Sender: TObject); begin SetEnabledBtn([Button2, Button3, Button4], False); end; |
Сообщ.
#7
,
|
|
|
Filka, отдельная процедура занимает больше места, чем объявление типа). К тому же что, если понадобится менять не только enabled, а, например, еще и visible?
|
Сообщ.
#8
,
|
|
|
Цитата Fr0sT @ И что?отдельная процедура занимает больше места, чем объявление типа Цитата Fr0sT @ В процедуре и менять...если понадобится менять не только enabled, а, например, еще и visible? Зато Open array parameters есть в любой версии Delphi... |
Сообщ.
#9
,
|
|
|
Filka, я ж и не спорю, что решить задачу можно несколькими способами. Просто делюсь более неочевидным.
|
Сообщ.
#10
,
|
|
|
Я тоже не спорю. Я просто хотел сказать, что подобное можно сделать и в старых версиях Delphi.
|
Сообщ.
#11
,
|
|
|
Вариант без generics тоже, возможно, сработает - мне не на чем проверить.
|
Сообщ.
#12
,
|
|
|
Цитата Fr0sT @ К тому же что, если понадобится менять не только enabled, а, например, еще и visible? Цитата Fr0sT @ В процедуре и менять... Зато Open array parameters есть в любой версии Delphi... Ну можно еще использовать универсальную функцию просто для создания и инициализации массива контролов в рамках подхода Fr0sT type TCtlArray = array of TControl; function GetCtlArray(Controls:array of TControl):TCtlArray; begin SetLength(Result,High(Controls)+1); Move(Controls[0],Result[0],SizeOf(TControl)*(High(Controls)+1)); end; |
Сообщ.
#13
,
|
|
|
Цитата Fr0sT @ Вариант без generics тоже, возможно, сработает - мне не на чем проверить. Например, в D7 не сработает, т.к. там нет конструкторов у дин. массивов. |