Как я могу пройти группу объектов к функции для создания?
-
25-09-2019 - |
Вопрос
Так что я работаю в Delphi 2007, и я очищаю свой код. Я пришел, чтобы заметить, что во многих процедурах я объявляю ряд разных переменных одного типа.
Например, одна процедура, на которой я смотрю, я объявляю 4 различных строковых списка, и я должен ввести var1 := TStringList.Create
для каждого.
У меня была идея сделать процедуру, которая взяла в открытом массиве переменных, моим списком 4 переменных, а затем создавать их все. Звонок будет чем-то вроде этого
CreateStringLists([var1,var2,var3,var4]);
Но как к мнению знаний, вы не можете передать открытый массив по ссылке и поэтому не делать то, что я надеялся. У кого-нибудь есть интересные идеи об этом?
Решение
Вы можете сделать все (или почти что угодно) с Delphi. Я не рекомендую использовать следующий код, чтобы узнать, что трюк возможен:
type
PStringList = ^TStringList;
procedure CreateStringLists(const SL: array of PStringList);
var
I: Integer;
begin
for I:= 0 to High(SL) do begin
SL[I]^:= TStringList.Create;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
SL1, SL2, SL3: TStringList;
begin
CreateStringLists([@SL1, @SL2, @SL3]);
SL3.Add('123');
Caption:= SL3[0];
SL1.Free;
SL2.Free;
SL3.Free;
end;
Другие советы
Часто в рефакторинге вам нужно взять очень Широкий вид кода. Почему «очистить» пару операций, как это, когда, скорее всего, вы не должны делать какие-либо из этих операций вообще?
В этом случае мне кажется подозренным, что у вас есть одна рутина, которая должна иметь дело с 4 отдельными строковыми списками. Это, кажется, не очень вероятно, будет иметь хорошую сплоченность. Возможно вместо этого должен быть один строковый перечисление в списке, называемую четыре раза. Поэтому я бы очень хотел увидеть всю рутину, а не комментарий к тому, как сделать этот нит в нем, красивее.
На самом деле, в чем проблема с 4 конструкторами?
Если в вашем контексте имеет смысл, вы можете совокупные декларации внутри специализированного Тобистлист.
type
TMyList<T:class,constructor> = class(TObjectList<T>)
public
procedure CreateItems(const ACount : integer);
end;
procedure TMyList<T>.CreateItems(const ACount: integer);
var
Index: Integer;
begin
for Index := 0 to (ACount - 1) do Add(T.Create);
end;
// Test procedure
procedure TestMe;
var
MyStringsList : TMyList<TStringList>;
begin
MyStringsList := TMyList<TStringList>.Create(True);
MyStringsList.CreateItems(10);
// ...
FreeAndNil(MyStringsList);
end;
Таким образом, вы можете специализировать ваш список.
Вы можете создать серию перегруженных версий с параметрами 2, 3, 4 и т. Д. Например:
procedure CreateStringLists(var L1, L2: TStringList); overload;
procedure CreateStringLists(var L1, L2, L3: TStringList); overload;
procedure CreateStringLists(var L1, L2, L3, L4: TStringList); overload;
procedure CreateStringLists(var L1, L2: TStringList);
begin
L1 := nil;
L2 := nil;
Try
L1 := TStringList.Create;
L2 := TStringList.Create;
Except
FreeAndNil(L2);
FreeAndNil(L1);
raise;
End;
end;
// etc.
Если бы я делал это, я бы написал сценарий для создания кода.
Как в сторону, в моем собственном коде, я бы написал InitialiseNil(L1, L2)
в начале этой функции и FreeAndNil(L2, L1)
в обработчике исключений. InitialiseNil
а также FreeAndNil
Функции, генерируемые очень простым сценарием Python, который включен в кодовую базу в качестве комментария, так что его можно повторно запустить. Рутина вроде CreareStringLists
Как определено выше только полезное, если у вас есть соответствующая рутина для освобождения их всех в одном выстрел. Это позволяет вам писать:
CreateStringLists(L1, L2);
Try
// do stuff with L1, L2
Finally
FreeAndNil(L2, L1);
End;
Наконец, я не говорю, что я обязательно сделаю это, но это подразумевается как наивный и прямой ответ на вопрос. Как утверждает, что надо это сделать, предполагает более глубокие проблемы в кодовой базе.