is it possible to make a Delphi TList immutable?
I searched in the delphi doc for a class similar to the unmodifiableList in java, but didn't found anything.
regards!
is it possible to make a Delphi TList immutable?
I searched in the delphi doc for a class similar to the unmodifiableList in java, but didn't found anything.
regards!
The Delphi RTL contains no classes that implement immutable or read-only lists. You will have to implement such a class yourself, or find a library that offers such functionality.
You could use the IReadOnlyList<T>
from Spring4D.
If you have an IList<T>
you just call AsReadOnlyList
(AsReadOnly
since 2.0) and it returns you the same instance as IReadOnlyList<T>
which does not provide methods to manipulate the list (no Add
, Delete
or setter for the Items
property).
However there is a difference to the unmodifiableList
from Java:
In Java you really get a List<T>
which will throw UnsupportedOperationException
when you try to modify it while in Spring4D which is mostly modeled after .NET you get something that you cannot call any modifying operations on.
The Delphi RTL contains no classes that implement immutable or read-only lists. You will have to implement such a class yourself, or find a library that offers such functionality.
Here is a simple Generic immutable list implementation with Map & Filter support :
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.
I'm using it in https://github.com/pierrejean-coudert/ReduxDelphi TodoMVC sample code.
© 2022 - 2024 — McMap. All rights reserved.