2013-12-01 3 views
2

У меня есть этот код, который не компилируется:Как иметь дело с открытым массивом TControls

function IsControlOneOf(AControl: TControl; AControls: array of TControl): Boolean; 
begin 
    Result := False; 
    // if AControls <> nil then // does not compile! 
    if Length(AControls) <> 0 then // this compiles 
    Result := AControl in AControls; // does not compile! 
end; 

Я, вероятно спутать динамический массив с открытым массивом.
Как я могу проверить это "AControl in AControls"? Должен ли я перебирать Low (AControls) в High (AControls) и проверять соответствие, или что?

Также есть способ установить значение по умолчанию для открытого массива?

AControls: array of TControl = [] 

Не компилируется.

+1

Лучше использовать 'TList' для этой коллекции. Вы реализуете функцию 'IsControlOneOf' с помощью одной строки, например' Result: = AControls.IndexOf (AControl) <> -1; '. За исключением того, что вы получите преимущества от простых операций, таких как вставка, удаление и т. Д. – TLama

+0

@TLama, я подумал об этом. но TList нужно создавать и создавать каждый раз, когда я передаю его функции, что является излишним я думаю ... – ZigiZ

+0

@TLama, что означает, что вы не можете использовать, например, конструкторы открытого массива –

ответ

5

Оператор in используется с наборами. Вы не можете использовать его для проверки наличия элемента в параметре открытого массива. На самом деле вы никогда не сможете использовать, чтобы проверить, является ли элемент членом любого типа массива. Вам нужно будет перебирать массив и проверять каждый элемент.

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

Наконец, я предлагаю вам не передавать параметры открытого массива по значению. В результате получается копия массива, которая, конечно же, дорогая для больших массивов, не говоря уже о необходимости. Объявите открытый параметр массива как const.


В вопросе редактирования вы задаете параметры по умолчанию. Вы не можете указывать значения по умолчанию для параметров открытого массива. Поэтому для достижения гибкости вам нужно будет использовать перегруженные процедуры.

+0

«не передавать параметры открытого массива по значению ": Должен ли я также передать AControl: TControl as const? – ZigiZ

+0

Это менее важно. Вы можете это сделать. Если вы используете const всегда, тогда он может получить немного подробностей. Вам решать. –

+0

10x для очень четкого ответа! – ZigiZ

2

Лучший способ справиться с этим перечислением:

function IsControlOneOf(AControl: TControl; const AControls: array of TControl): Boolean; 
var 
    lControl: TControl; 
begin 
    for lControl in AControls do 
    if lControl = AControl then 
     exit(true); 
    result := False; 
end; 

К сожалению, это помечено Delphi 7, так что вы не имеете некоторые из этих особенностей языка. Поэтому вам придется сделать это старомодно:

function IsControlOneOf(AControl: TControl; const AControls: array of TControl): Boolean; 
var 
    i: integer; 
begin 
    for i := 0 to high(AControls) do 
    if AControl = AControls[i] then 
    begin 
     result := true; 
     exit; 
    end; 
    result := False; 
end; 
+0

Без темы. Вы действительно используете выход и результат в той же процедуре? –

+0

@David, Delphi 7 еще этого не знал. – TLama

+0

@TLama Вы неправильно понимаете. Я был неясен. Я удивлен, увидев exit (true) и результат: = ... в той же процедуре. –

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