程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 擴展 delphi 泛型 以實現類似lambda功能 , C#中的any count first last 等擴展方法

擴展 delphi 泛型 以實現類似lambda功能 , C#中的any count first last 等擴展方法

編輯:Delphi

擴展 delphi 泛型 以實現類似lambda功能 , C#中的any count first last 等擴展方法

在C#中對泛型的擴展,輸入參數是泛型本身的內容,返回值則是bool.基於這一點,開始構造在delphi下如何實現.

首先
1.delphi 是支持匿名函數的其語法為:
名稱 = reference to 函數類型定義
例如:
TFun = reference to function(const num: Integer): Integer;

2.對泛型的擴展的語法如下:
TList<T> = class(Generics.Collections.TList<T>)
public
***********
end;

有了如上的兩點,便可以實現我們想要的功能了.其主要思路為:
為泛型擴展的any count方法添加類型為"Ibool接口"的參數.Ibool接口類型的參數就是泛型本身的內容,返回值則是Boolean

在調用這些擴展時,只需要構造出一個支持Ibool接口的對像就可以了.

對於Ibool接口,支持Ibool接口的對像,any等擴展方法之間的關系請細細考慮.對高手來說很簡單了吧,就是一個簡單的設計模式.

主要代碼,注釋如下:
unit UCryHelper;

interface
uses
Generics.Collections;
type
IBool<T>=interface //這就是Ibool接口的定義
function Compare(Right: T): Boolean;
end;

TBoolsion<T> = reference to function( Right: T): Boolean;//匿名函數 因為是對泛型的支持所以要有那個"T". 這個的類型與Ibool接口方法的類型是一樣的,定義成這樣後,用這個匿名函數連接你寫的實際的函數體和泛型

TBool<T>=class(TInterfacedObject, IBool<T>) //這是支持IBool接口的對像,這是虛函數,實際的執行者是下邊的定義.
public
class function Construct(const EqualityComparison: TBoolsion<T>): IBool<T>;
function Compare(Right: T): Boolean;virtual; abstract;
end;

TDelegatedBool<T> = class(TBool<T>) //前三個類型是必備的類型,這行則是實際的執行者.
private
FEquals: TBoolsion<T>;
public
constructor Create(const AEquals: TBoolsion<T>);
function Compare(Right: T): Boolean; overload; override;
end;

TList<T> = class(Generics.Collections.TList<T>) //這是對泛型的擴展,不用多說了.
public
type
TDynArray = array of T;
function ToArray: TDynArray;
function Any(const AComparer: IBool<T>):Boolean; //擴展方法Any的參數為IBool<T>返回值是Boolean
end;
implementation


function TList<T>.Any(const AComparer: IBool<T>): Boolean;
var
one:T;
begin
Result:=False;
for one in Self do
begin
if AComparer.Compare(one) then
begin
Result:=True;
Exit;
end;
end;
end;

function TList<T>.ToArray: TDynArray;
var
I: Integer;
begin
SetLength(Result, self.Count);
for I := 0 to Self.Count - 1 do
begin
Result[I] := Self[I];
end;
end;
{ TBool<T> }

class function TBool<T>.Construct(const EqualityComparison: TBoolsion<T>): IBool<T>;
begin
Result:= TDelegatedBool<T>.Create(EqualityComparison);
end;

{ TDelegatedBool<T> }

function TDelegatedBool<T>.Compare(Right: T): Boolean;
begin
Result := FEquals(Right);
end;

constructor TDelegatedBool<T>.Create(const AEquals: TBoolsion<T>);
begin
FEquals:= AEquals;
end;
end.


最終的調用就是這樣用了.先use UCryHelper 然後

procedure TfrmSampleInput.btnQuitClick(Sender: TObject);
var
listint:TList<Integer>;
boolCal:IBool<Integer>;
begin
inherited;
listint:=TList<Integer>.Create;
listint.Add(1);
listint.Add(33);
listint.Add(3);
listint.Add(4);

boolCal:=TBool<Integer>.Construct(
function ( Avalue: integer): Boolean
begin
result := Avalue=listint.Count;
end
);
if(listint.Any(boolCal)) then
ShowMessage('OOKK!!');
{如果想把boolCal:IBool<Integer>;的聲明省了,這樣用也是可以的,怎麼樣?和C#裡的any方法差不多吧.
if listint.Any(Tbool<Integer>.Construct(function(Avalue:Integer):Boolean
begin
result := Avalue=listint.Count;
end
)) then
ShowMessage('OOKK!!');}
listint.Free;
end;

以上就是一個擴展any的實現,有了這個any,再擴展count first last等其它方法還不就簡單了?快試試吧.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved