我想在Delphi XE5中使用带有子列表的通用TList记录:
type
TMyRecord=record
Value1: Real;
SubList: TList<Integer>;
end;
TMyListOfRecords=TList<TMyRecord>;
var
MyListOfRecords: TMyListOfRecords;
无法分配记录字段:
MyListOfRecords[0].Value1:=2.24;
要么
MyListOfRecords[0].SubList:=TList<Integer>.Create;
将导致编译器“左侧无法分配”错误 .
另见:How to modify TList<record> value?
以下解决方法有效:
AMyRecord:=MyListOfRecords[0];
AMyRecord.Value1:=2.24;
AMyRecord.SubList:=TList<Integer>.Create;
AMyRecord.SubList.Add(33);
MyListOfRecords[0]:=AMyRecord;
由于性能问题,我想避免将数据复制到临时AMyrecord . 我宁愿直接访问记录字段和子列表 .
处理这个问题的最佳方法是什么?
1 回答
该列表通过List属性公开其内部存储(动态数组) . 所以你可以写:
与具有 Value 副本的替代方案相比,这是否会在性能方面产生任何可衡量的差异,我无法分辨 . 值得检查一下 .
正如@LURD所说,
List
返回内部存储 . 这可能超过Count
元素 . 具体来说,它有Capacity
个元素 . 因此,如果您使用它,则必须使用数组索引访问元素,方法是0
到Count-1
. 还要记住,对列表大小的修改可能涉及重新分配,因此内部存储可能会移动 . 您对List
的任何引用仅在下次重新分配之前有效 .这些警告应该告诉您,如果性能限制要求,您只考虑使用
List
. 即使这样,也要谨慎使用它 .在我的代码库中,我有
TList<T>
的替代方法,其Items[]
属性返回指向该元素的指针 . 容器仍然存储为动态数组,以实现高效的内存布局 . 我更喜欢List
属性的这个选项,因为我觉得它导致更清晰的代码 .好的,你要求查看我的list类,它返回指向元素的指针 . 这里是:
现在,需要一些解释 . 基类
TBaseValueList<T>
是我对TList<T>
的替代 . 如果您愿意,可以替换TList<T>
. 我没有,因为我的基类没有Items
属性 . 那是因为我希望专门的类能够引入它 . 我的另一个专业是:我的
TBaseValueList<T>
的实现非常明显 . 它与TList<T>
非常相似 . 我不是很明显 .作为获取元素引用的简单方法,您可以像这样包装
List
:如果你想要一套比Delphi更丰富的容器,你可能会关注Spring4D . 虽然我不确定他们是否有类似我的容器返回引用 .