Delphi 我的objectlist中有多少ObjectType
我使用DELPHI对象列表存储对Tforms类项的引用。在创建表单并将表单插入该列表后,还有一些表单被删除。。。。并执行其他处理步骤。 之后,我需要评估objectlist的内容Delphi 我的objectlist中有多少ObjectType,delphi,Delphi,我使用DELPHI对象列表存储对Tforms类项的引用。在创建表单并将表单插入该列表后,还有一些表单被删除。。。。并执行其他处理步骤。 之后,我需要评估objectlist的内容 aForm1 : TMyForm_1 ; aForm2 : TMyForm_1 ; aForm3 : TMyForm_1 ; MyObjectList := TObjectList.create; .... MyObjectList.add(aForm1) ; // and als
aForm1 : TMyForm_1 ;
aForm2 : TMyForm_1 ;
aForm3 : TMyForm_1 ;
MyObjectList := TObjectList.create;
....
MyObjectList.add(aForm1) ; // and also the other forms , many time each ...
我的列表中还有多少来自TMyform_1类型的表单实例?
循环所有列表元素并检查类类型是我解决该任务的想法
for i := 0 ....
if (MyObjectList.items[i] is TMyForm_1) ...
有没有更优雅的方法来解决这个问题?
首先我只需要知道我的列表中有一个TMyForm_1类型,然后给我第一个位置,最后从这个位置。。。转到此列表中的下一个元素。TObjectList不提供任何基于容器成员的运行时类型返回信息的方法。您必须使用
is
操作符编写自己的功能。我能想到的最优雅的方法是:
uses
Generics.Collections;
var
dict: TDictionary<TClass,Integer>;
obj: TObject;
i: Integer;
begin
// ...
for obj in MyObjectList do
if dict.TryGetValue(obj.ClassType, i) then
dict[obj.ClassType] := i + 1
else
dict.Add(obj.ClassType, 1);
// ...
end;
使用
仿制药。收藏;
变量
dict:t词典;
对象:对象;
i:整数;
开始
// ...
对于MyObjectList中的obj,请执行以下操作:
如果dict.TryGetValue(obj.ClassType,i),则
dict[obj.ClassType]:=i+1
其他的
dict.Add(obj.ClassType,1);
// ...
结束;
您可以为TObjectList
编写一个类帮助器,并添加一个函数,返回给定类型的项数组
type
TObjectListHelper = class helper for TObjectList
function GetItemsByType<T : class> : TArray<T>;
end;
{ TObjectListHelper }
function TObjectListHelper.GetItemsByType<T> : TArray<T>;
var
LIdx : Integer;
LItem : TObject;
LCount : Integer;
begin
SetLength( Result, Self.Count );
LCount := 0;
for LIdx := 0 to Self.Count - 1 do
begin
LItem := Self.Items[LIdx];
if LItem is T then
begin
Result[LCount] := LItem as T;
Inc( LCount );
end;
end;
SetLength( Result, LCount );
end;
类型
TObjectListHelper=TObjectList的类帮助器
函数GetItemsByType:TArray;
结束;
{TObjectListHelper}
函数TObjectListHelper.GetItemsByType:TArray;
变量
LIdx:整数;
LItem:TObject;
l计数:整数;
开始
SetLength(结果、自计数);
l计数:=0;
对于LIdx:=0到Self.Count-1 do
开始
LItem:=Self.Items[LIdx];
如果LItem是T,那么
开始
结果[LCount]:=LItem作为T;
公司(LCount);
结束;
结束;
设置长度(结果,LCount);
结束;
在应用程序中,您可以这样使用它
var
LItem : TMyForm_1;
begin
for LItem in MyObjectList.GetItemsByType<TMyForm_1> do
begin
// do something with LItem
end;
end;
var
LItem:TMyForm_1;
开始
对于MyObjectList.GetItemsByType do中的LItem
开始
//用LItem做点什么
结束;
结束;
您使用传统的TObjectList
而不是类型安全的通用TObjectList
或TList
有什么好的理由吗?我很好奇。为什么在一个对象列表中会有同一表单的多个实例?@Andy_D我猜是因为它可能是某种编辑表单或类似的表单,您可以编辑多个实例?请注意,您的程序已经在程序中保留了所有表单的列表。再问一次,你的最终目标是什么?是否要根据表单类型对所有表单执行特殊操作?还有更好的解决方案,但你必须提出正确的问题……这并不能真正实现你的要求。根据最后一段,第一项任务是确定列表中是否存在给定类的任何项。这会计算每个类中有多少个类,当它在第一次出现时就足以停止时,会遍历整个列表。这也会根据类层次结构的叶类型进行分类,但是is
操作符也会检查所有祖先类。第二个任务是确定列表中的哪个项与请求的类匹配,第三个任务是查找该类的下一项;这段代码两者都没有。他问“我的列表中还有多少来自TMyform_1类型的表单实例?”他显示的代码执行了is操作。但实际上我的回答是指他的要求(问题),而不是他展示的代码。也许他应该更清楚地说明他的要求。至于其他问题——我认为,除非你想创造一些荒谬的开销,否则在列表中循环是可以的,所以这不需要在我的回答中提及。