Как я могу передать группу объектов в функцию для создания? - PullRequest
0 голосов
/ 05 января 2011

Итак, я работаю в Delphi 2007 и очищаю свой код. Я заметил, что во многих процедурах я объявляю несколько различных переменных одного типа.

например, одна процедура, которую я сейчас смотрю, я объявляю 4 разных списка строк, и мне нужно набрать var1 := TStringList.Create для каждого.

У меня была идея сделать процедуру, которая взяла бы открытый массив переменных, мой список из 4 переменных, а затем создать их все. Звонок будет примерно таким

CreateStringLists([var1,var2,var3,var4]);

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

Ответы [ 5 ]

5 голосов
/ 05 января 2011

Зачастую при рефакторинге вам нужно иметь очень широкое представление кода.Зачем «очищать» пару таких операций, когда, скорее всего, вам вообще не следует выполнять какие-либо из этих операций?

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

4 голосов
/ 05 января 2011

Вы можете делать что угодно (или почти все) с 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;
1 голос
/ 06 января 2011

Если это имеет смысл в вашем контексте, вы можете агрегировать объявления внутри специализированного TObjectList .

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;

Так что вы можете специализировать свой список.

1 голос
/ 05 января 2011

Собственно, в чем проблема с 4 конструкторами?

1 голос
/ 05 января 2011

Вы можете создать серию перегруженных версий с параметрами 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;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...