• 扩展 delphi 泛型 以实现类似lambda功能 , C#中的any count first last 等扩展方法


    扩展 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等其它方法还不就简单了?快试试吧.

    http://www.cnblogs.com/ttgss/p/3252469.html

  • 相关阅读:
    python开发mysql:索引
    学习笔记之English
    本周学习小结(25/03
    本周学习小结(18/03
    本周学习小结(11/03
    学习笔记之Machine Learning Crash Course | Google Developers
    本周学习小结
    学习笔记之Fluent Python
    Leetcode 4. Median of Two Sorted Arrays
    学习笔记之Python爬虫
  • 原文地址:https://www.cnblogs.com/findumars/p/6008451.html
Copyright © 2020-2023  润新知