该列表通过 List
属性公开其内部存储,该存储是一个动态数组。因此,您可以编写以下代码:
MyListOfRecords.List[0].Value1 := 2.24
无论与值复制的替代方案相比是否在性能上有任何可衡量的差异,我无法确定。这值得检查。
正如@LURD所说,List返回内部存储。这可能多于Count个元素。具体来说,它有Capacity个元素。因此,如果您使用它,必须使用数组索引访问元素0到Count-1。还要记住,对列表大小的修改可能涉及重新分配,因此内部存储可能会移动。您对List所做的任何引用仅在下一次重新分配之前有效。
这些警告应提示您仅在性能约束要求时考虑使用List。即使是这样,也要节制使用。
在我的代码库中,我有一个替代TList的选择,其Items[]属性返回指向元素的指针。容器仍然以动态数组存储,以实现高效的内存布局。我更喜欢这个选项而不是List属性,因为我觉得它可以带来更清晰的代码。
好的,你想看看我的返回指向元素的列表类,请看这里:
type
TReferenceList<T> = class(TBaseValueList<T>)
type
P = ^T;
private
function GetItem(Index: Integer): P;
public
property Items[Index: Integer]: P read GetItem; default;
public
public
function GetEnumerator: TEnumerator;
function Enumerator(Forwards: Boolean): TEnumeratorFactory;
function ReverseEnumerator: TEnumeratorFactory;
function IndexedEnumerator: TIndexedEnumeratorFactory;
end;
现在需要一些解释。基类TBaseValueList<T>
是我替代TList<T>
的选择。如果你愿意,你可以替换为TList<T>
。但我不这样做,因为我的基类没有一个Items
属性。这是因为我希望专门的类来引入它。我的另一个特化是:
type
TValueList<T> = class(TBaseValueList<T>)
private
function GetItem(Index: Integer): T;
procedure SetItem(Index: Integer; const Value: T);
public
property Items[Index: Integer]: T read GetItem write SetItem; default;
end;
我实现的TBaseValueList<T>
非常明显。它非常类似于TList<T>
。我认为您真的不需要看到任何实现细节,因为这都是很明显的。
作为一个获取元素引用的简单方法,您可以像这样包装List
:
type
TMyList<T> = class(TList<T>)
public
type
P = ^T;
private
function GetRef(Index: Integer): P;
public
property Ref[Index: Integer]: P read GetRef;
end;
function TMyList<T>.GetRef(Index: Integer): P;
begin
Result := @List[Index];
end;
如果您需要比Delphi提供更丰富的容器集,您可以考虑使用Spring4D。不过我不确定他们是否有类似于返回引用的容器。
TList<T>
几乎相同。它没有Items
属性,这是主要区别。你可以从TList<T>
中获取代码,并删除Items
、GetItem
和SetItem
,然后就可以接近了。枚举器也很酷。我不想以可编译的形式展示所有代码。我不确定世界是否需要另一组容器。你应该能够从我给你的内容中自己理解这些想法。希望如此。你还应该仔细检查性能是否是一个问题。 - David HeffernanTList<T>
并添加一个属性,使用我描述的List
属性返回一个项目的引用。那将是简单的方法。或者甚至可以使用类助手来实现。 - David Heffernan