2014-03-27 82 views
2

是否有可能使Delphi TList不可變?
我在delphi文檔中搜索類似於java中的unmodifiableList的類,但沒有找到任何東西。使得Delphi TList不可變

問候!

回答

2

Delphi RTL不包含實現不可變或只讀列表的類。你將不得不自己實現這樣一個類,或者找到一個提供這種功能的庫。

4

您可以使用Spring4D的IReadOnlyList<T>

如果你有一個IList<T>你只需要調用AsReadOnlyList並返回你相同的實例爲IReadOnlyList<T>不提供方法來操作的列表(無AddDelete或setter的Items屬性)。

然而,有從Java到unmodifiableList一個區別:

在Java中你真的得到了List<T>這將引發UnsupportedOperationException當您嘗試修改它,而在Spring4D這是.NET爲藍本,你得到的東西,你不能調用任何修改操作。

0

下面是一個簡單通用的不可變列表實現與地圖&過濾器支持:

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示例代碼。