Вопрос

Так что я работаю в 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;

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top