zoukankan      html  css  js  c++  java
  • 扩展 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

  • 相关阅读:
    CodeForces 660D Number of Parallelograms
    【POJ 1082】 Calendar Game
    【POJ 2352】 Stars
    【POJ 2481】 Cows
    【POJ 1733】 Parity Game
    【NOI 2002】 银河英雄传说
    【NOI 2015】 程序自动分析
    【POJ 1704】 Georgia and Bob
    【HDU 2176】 取(m堆)石子游戏
    【SDOI 2016】 排列计数
  • 原文地址:https://www.cnblogs.com/findumars/p/6008451.html
Copyright © 2011-2022 走看看