どのようにして作成するための関数にオブジェクトのグループを渡すことができますか?
-
25-09-2019 - |
質問
私は、Delphi 2007年に働いていると私は私のコードをクリーンアップしていますので。私は非常に多くの手順では、私は、同じタイプの異なる変数の数を宣言した旨の通知に来ています。
たとえば、私は見ています1つの手順は、今私は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つの別個の文字列のリストに対処することを1つのルーチンを持っているように私には思えるsuspicous。それは良いの結束を持っている可能性が高いようではありません。おそらく、代わりにそれが4回と呼ばれる1つの文字列のリスト処理ルーチンでなければなりません。だから私は思います本当にルーチン全体を見たい、というよりもきれいにそれにこの1のNITを作成する方法についてのコメントます。
実際には、4つのコンストラクタに問題が何ですか?
、あなたは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;
あなたのリストを専門にすることができますので。
あなたは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;
最後に、私は必ずしもこれを行うだろうと言っていないんだけど、これは質問へのナイーブとの直接の答えとして意味しています。 T.E.D @として。状態は、これを実行する必要がコードベースに、より深い問題を示唆してます。