所以我在Delphi 2007工作,我正在清理我的代码。我注意到在很多程序中我声明了许多相同类型的不同变量。
例如我现在正在查看的一个程序我声明了4个不同的字符串列表,我必须为每个字符串键入var1 := TStringList.Create
。
我有一个想法是创建一个过程,该过程接受一个开放的变量数组,我的4个变量列表,然后创建所有变量。电话会是这样的
CreateStringLists([var1,var2,var3,var4]);
但据我所知,你不能通过引用传递开放数组,因此不能做我希望的事情。有没有人对此有任何有趣的想法?
答案 0 :(得分:5)
通常在重构时,您需要使用非常的代码视图。为什么“清理”这样的几个操作,很可能你根本不应该做任何这些操作?
在这种情况下,我似乎怀疑你有一个例程需要处理4个单独的字符串列表。这似乎不太可能具有良好的凝聚力。也许它应该是一个称为四次的字符串列表处理例程。所以我真的很想看看整个例行程序,而不是评论如何使这个例子变得更漂亮。
答案 1 :(得分:4)
你可以用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;
答案 2 :(得分:1)
您可以使用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。状态,需要这样做表明代码库中存在更深层次的问题。
答案 3 :(得分:1)
实际上,4个构造函数有什么问题?
答案 4 :(得分:1)
如果在您的上下文中有意义,您可以在专门的 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;
所以你可以专门列出你的名单。