DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: randy522732557
今日帖子: 24
在线用户: 13
导航: 论坛 -> 移动应用开发 斑竹:flyers,iamdream  
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/9/1 1:16:03
标题:
新手请问helper的问题 浏览:821
加入我的收藏
楼主: 比如我想给数组添加判断是否包含某元素的功能

TMyArray=class helper for tarray
  function Contains(Item:string):Boolean;overload;
  function Contains(Item:integer):Boolean;overload;
end;

//TMyArray=class helper for array
//TMyArray=class helper for array of string
//TMyArray=class helper for tarray<string>
为什么上面写法三种通不过,是因为它们不是类吗?

function TMyArray.Contains(Item: string): Boolean;
var
  i: Integer;
begin
  for i := 0 to Length(Self) - 1 do
    if string(Self[i]) = Item then
      result := True;
end;

假如就按通过的Tarray来写,函数里面的Length(Self)又会报错,是还需要继承什么吗?求解答.
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2023/9/1 1:49:26
1楼: 你的tarray是一个类,怎么能直接当作数组操作?而且tarray类本身就是array of T的一个助手类,你再helper的话,那也要按它的原理,把你需要的数组作为参数传进去。
比如:
funciton Contains<T>(arr: TArray<T>; itm: T): Boolean;
----------------------------------------------
--
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/9/1 2:17:29
2楼: function TMyArray.Contains<t>(arr: tarray<t>; Item: t): Boolean;
var
  i: Integer;
begin
  for i := 0 to Length(arr) - 1 do
    if TValue.From<t>(arr[i]).ToString = TValue.From<t>(Item).ToString then
      result := True;
  result := false;
end;
但是这样的话使用的时候比如
var ss:tarray<string>;b:Boolean;
b:=TArray.contains<string>( ss,'123');
是这样用吗 会报错
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/1 3:11:03
3楼: here a way rude but can works for basic types...


uses
  System.Rtti;

type
  TMyArrayString_1 = TArray<string>;

  TMyHlpTArray_1 = record helper for TMyArrayString_1
    function ContainsThis(AValue: string): boolean; overload;
    function ContainsThis<T>(AValue: T): boolean; overload;
  end;

  { TMyHlpTArray<T> }

function TMyHlpTArray_1.ContainsThis(AValue: string): boolean;
begin
  result := false;
  //
  for var V in Self do
    if (V = AValue) then // CompareStr(s1,s2)
      begin
        result := true;
        break;
      end;
end;

function TMyHlpTArray_1.ContainsThis<T>(AValue: T): boolean;
begin
  result := false;
  //
  for var V in Self do
    if (V = TValue.From<T>(AValue).AsString) then // CompareStr(s1,s2)
      begin
        result := true;
        break;
      end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  LValues_1: TMyArrayString_1;
begin
  LValues_1 := ['hello', 'world', 'delphi'];
  //
  if LValues_1.ContainsThis('delphi') then
    ShowMessage('Delphi found')
  else
    ShowMessage('Delphi NOT found');
  //
  if LValues_1.ContainsThis<string>('delphi') then
    ShowMessage('Delphi found')
  else
    ShowMessage('Delphi NOT found');
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2023/9/1 9:18:53
4楼: program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,Generics.Collections, Generics.Defaults;;

  type
  TMyHelper = class
  public
    class function contains<T>(arr:array of T; item:T) :boolean;
  end;

  TMyArray<T> = array of T;

  TMyArray=class(tarray)
   class function contains<T>(arr:array of T; item:T) :boolean;
  end;

  THelpArray=class helper for tarray
   class function contains<T>(arr:array of T; item:T) :boolean;
  end;

{ TMyHelper }

class function TMyHelper.contains<T>(arr: array of T; item: T): boolean;
var
  i:integer;
begin
  Result:=false;
  for I := Low(arr) to High(arr) do
  begin
    if arr[i]=item then
    begin
      Result := true;
      Break;
    end;
  end;
end;

{ TMyArray }

class function TMyArray.contains<T>(arr: array of T; item: T): boolean;
var
  i:integer;
begin
  Result:=false;
  for I := Low(arr) to High(arr) do
  begin
    if arr[i]=item then
    begin
      Result := true;
      Break;
    end;
  end;

end;

{ THelpArray }

class function THelpArray.contains<T>(arr:array of T; item:T): boolean;
var
  i:integer;
begin
  Result:=false;
  for I := Low(arr) to High(arr) do
  begin
    if arr[i]=item then
    begin
      Result := true;
      Break;
    end;
  end;
end;

begin
  try
     Writeln(TMyHelper.contains<integer>([1,2,3,4],2));
     Writeln(TMyHelper.contains<char>('12345'.ToCharArray(0,4),'2'));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

引用Generics.Collections, Generics.Defaults;
TArray本身就是个泛型工具类
----------------------------------------------
-
作者:
男 wk_knife (wk_knife) ★☆☆☆☆ -
盒子活跃会员
2023/9/1 9:41:57
5楼: TArray本身就不包含array数组的数据,它不包含成员变量,所有的成员函数都是类函数,也就是静态函数。所以楼主的声明即便通过,也不可能知道数组在哪里。
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/1 12:22:41
6楼: My "Helper" works!

procedure TForm1.Button1Click(Sender: TObject);
var
  LValues_1: TMyArrayString_1;
begin
  LValues_1 := ['hello', 'world', 'delphi'];
  //
  if LValues_1.ContainsThis('delphi') then
    ShowMessage('Delphi found')
  else
    ShowMessage('Delphi NOT found');
  //
  if LValues_1.ContainsThis<string>('delphi') then
    ShowMessage('Delphi found')
  else
    ShowMessage('Delphi NOT found');
end;
此帖子包含附件:
GIF 图像
大小:446.4K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 janker (janker) ★☆☆☆☆ -
盒子活跃会员
2023/9/1 16:53:12
7楼: helper不支持泛型:
TArrayHelper<T> = record helper for TArray<T>

不能这样定义,感觉就没有多大作用了,总不能每个具体类型就定义一个。

System单元定义:
TArray<T> = array of T;

System.Generics.Collections 单元定义:
TArray = class

这个TArray是个类,辅助各种数组操作的。
所以想方便的操作数组,直接用System.Generics.Collections的TArray来操作就好,如果想添加功能,可以扩展System.Generics.Collections 单元TArray

TArrayHelper = class helper for TArray
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2023/9/1 18:36:34
8楼: 首先就是,用泛型做比较的话,不能直接粗暴的用tvalue的tostring来比较,也不能直接用等号,要分类型比较。
其次就是,没发现哪里报错,楼主至少要有个错误信息。
而且有这么多回贴了,连版主都回贴了,至少要有个结果反馈才行。不能就这么突然没下文了。
至于例子嘛倒是随手写了一个,没测试没编译,具体大概就是这么个意思了:

type
  TArrayHelper = class helper for TArray
  public
    class function IndexOf<T>(const theArray: array of T; const theItem: T): Integer; static;
    class function Contains<T>(const theArray: array of T; const theItem: T): Boolean; static;
  end;



class function TArrayHelper.Contains<T>(const theArray: array of T;
  const theItem: T): Boolean;
begin
  Result := IndexOf(theArray, theItem) > -1;
end;

class function TArrayHelper.IndexOf<T>(const theArray: array of T;
  const theItem: T): Integer;
var
  nIndex: Integer;
begin
  /// 分类型判断,具体可以参照tvalue的tostring方法。
  case PTypeInfo(System.TypeInfo(T))^.Kind of
    tkString,
    tkUString,
    tkLString,
    tkWString:
      for nIndex := Low(theArray) to High(theArray) do
        if (TValue.From(theItem).ToString() = TValue.From(theArray[nIndex]).ToString()) then
          Exit(nIndex);

    tkArray,
    tkDynArray,
    tkClass,
    tkMethod,
    tkInterface,
    tkClassRef,
    tkPointer,
    tkProcedure:
      ; /// 其他处理方式;

    else
      for nIndex := Low(theArray) to High(theArray) do
        if (CompareMem(@theItem, @(theArray[nIndex]), SizeOf(T))) then
          Exit(nIndex);
  end;

  Exit(-1);
end;



调用:
var
  ai: TArray<Integer>;
  ac: TArray<Char>;
  &as: TArray<String>;
  i: Integer;
begin
  SetLength(ai, 1000);
  SetLength(ac, 26);
  SetLength(&as, 100);
  for i := Low(ai) to High(ai) do
    ai[i] := i;
  for i := Low(ac) to High(ac) do
    ac[i] := Chr(i + Ord('A'));
  for i := Low(&as) to High(&as) do
    &as[i] := Format('08x', [i]);

  if TArray.Contains(ai, 123) then
    ShowMessage('yes');

  if TArray.Contains<Char>(ac, 'Z') then
    ShowMessage('yes');

  if TArray.Contains<String>(&as, 'aaabbb') then
    ShowMessage('yes');

  ShowMessage(TArray.IndexOf([0,1,2,3,4,5,6,7,8,9], 10).ToString());


  SetLength(&as, 0);
  SetLength(ac, 0);
  SetLength(ai, 0);
end;
----------------------------------------------
--
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/9/1 18:37:49
8楼: 感谢各位高手 这些办法还不如直接来个函数了 看来delphi直接像c#那样 if ss.contains(s) then这样是不可能实现的了 只能把数组当参数传还要指明类型才可以
----------------------------------------------
-
作者:
男 bahamut8348 (leonna) ★☆☆☆☆ -
普通会员
2023/9/1 19:01:05
9楼: 在这些新特性上,delphi的确都是干了个半吊子,不单是对泛型以及对友元类的支持,在运算符的重载上也很别扭,远没有c++那样灵活,要是再对比c#这样的动态语言就更没有优势了。
总之就是别扭的很。
所以,关键还是看你怎么方便,并不一定需要新特性,只要能让你更方便的实现你的需求就是合适你的方案。
----------------------------------------------
--
作者:
男 mp654kk (mp654kk) ▲△△△△ -
普通会员
2023/9/1 19:03:52
10楼: @bahamut8348 好的 多谢 也许delphi这样是为了性能考虑
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行195.3125毫秒 RSS