是否可以使 Delphi TList 不可变?
我在 delphi 文档中搜索了一个类似于 java 中的 unmodifiableList 的类,但没有找到任何东西。
问候!
是否可以使 Delphi TList 不可变?
我在 delphi 文档中搜索了一个类似于 java 中的 unmodifiableList 的类,但没有找到任何东西。
问候!
您可以使用IReadOnlyList<T>
Spring4D 中的。
如果您有一个IList<T>
您只需调用AsReadOnlyList
(自 2.0 起),它会返回与不提供操作列表的方法AsReadOnly
相同的实例(no或属性的 setter )。IReadOnlyList<T>
Add
Delete
Items
但是,unmodifiableList
与 Java 的不同之处在于:
在 Java 中,当您尝试修改它时,您确实会得到一个List<T>
抛出的UnsupportedOperationException
结果,而在 Spring4D 中,它主要是在 .NET 之后建模的,您会得到一些您无法调用任何修改操作的东西。
Delphi RTL 不包含实现不可变或只读列表的类。您必须自己实现这样的类,或者找到提供此类功能的库。
这是一个简单的通用不可变列表实现,支持 Map & Filter :
unit Immutable;
interface
uses
System.Generics.Collections;
type
TFilter<TItem> = reference to function(AItem: TItem): Boolean;
TMapper<TItem> = reference to function(AItem: TItem): TItem;
IImmutableList<TItem> = interface
function Insert(Index: Integer; AItem: TItem): IImmutableList<TItem> ;
function Filter(AFilter: TFilter<TItem>): IImmutableList<TItem> ;
function Map(AMapper: TMapper<TItem>): IImmutableList<TItem> ;
function GetEnumerator: TEnumerator<TItem>;
end;
TImmutableList<TItem> = class(TInterfacedObject, IImmutableList<TItem>)
private
FList: TList<TItem>;
public
constructor Create(); overload;
constructor Create(AImmutableList: IImmutableList<TItem>); overload;
destructor Destroy; override;
function Insert(Index: Integer; AItem: TItem): IImmutableList<TItem>;
function Filter(AFilter: TFilter<TItem>): IImmutableList<TItem>;
function Map(AMapper: TMapper<TItem>): IImmutableList<TItem>;
function GetEnumerator: TEnumerator<TItem>;
end;
implementation
{ TImmutableList<TItem> }
constructor TImmutableList<TItem>.Create;
begin
FList := TList<TItem>.Create;
end;
constructor TImmutableList<TItem>.Create(AImmutableList: IImmutableList<TItem>);
var
AItem : TItem;
begin
FList := TList<TItem>.Create;
for AItem in AImmutableList do
FList.Add(AItem);
end;
destructor TImmutableList<TItem>.Destroy;
begin
FList.Free;
inherited;
end;
function TImmutableList<TItem>.GetEnumerator: TEnumerator<TItem>;
begin
Result := FList.GetEnumerator;
end;
function TImmutableList<TItem>.Insert(Index: Integer; AItem: TItem): IImmutableList<TItem>;
var
NewList : TImmutableList<TItem>;
begin
NewList := TImmutableList<TItem>.Create(Self);
TImmutableList<TItem>(NewList).FList.Insert(Index, AItem);
Result := NewList;
end;
function TImmutableList<TItem>.Filter(AFilter: TFilter<TItem>): IImmutableList<TItem>;
var
AItem : TItem;
NewList : TImmutableList<TItem>;
begin
NewList := TImmutableList<TItem>.Create();
for AItem in FList do begin
if AFilter(AItem) then
TImmutableList<TItem>(NewList).FList.Add(AItem)
end;
Result := NewList;
end;
function TImmutableList<TItem>.Map(AMapper: TMapper<TItem>): IImmutableList<TItem>;
var
AItem : TItem;
NewList : TImmutableList<TItem>;
begin
NewList := TImmutableList<TItem>.Create();
for AItem in FList do begin
TImmutableList<TItem>(NewList).FList.Add( AMapper(AItem))
end;
Result := NewList;
end;
end.
我在https://github.com/pierrejean-coudert/ReduxDelphi TodoMVC 示例代码中使用它。