是否可以使Delphi TList不可变?
我在delphi doc中搜索了一个类似于java中unmodifiableList的类,但没有找到任何东西。
问候!
答案 0 :(得分:4)
您可以使用Spring4D的IReadOnlyList<T>
。
如果您有IList<T>
,则只需拨打AsReadOnlyList
即可返回与IReadOnlyList<T>
相同的实例,该实例不提供操作列表的方法(无Add
, Delete
属性的Items
或setter。
然而,Java中的unmodifiableList
存在差异:
在Java中,你真的得到一个List<T>
当你尝试修改它时会抛出UnsupportedOperationException
,而在Spring4D中,它主要是在.NET之后建模的,你会得到一些你不能调用任何修改操作的东西。
答案 1 :(得分:2)
Delphi RTL不包含实现不可变列表或只读列表的类。您必须自己实现这样的类,或者找到提供此类功能的库。
答案 2 :(得分:0)
这是一个简单的通用不可变列表实现,包含Map&amp;过滤器支持:
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示例代码中使用它。