如何使用泛型处理普通的动态数组?

Joh*_*ica 2 delphi generics

我知道如何操纵像TList等派生的泛型类.

但是,当我想操纵一个普通的动态数组时,我遇到了困难.

如何将以下代码转换为使用泛型的版本?

//code A
function CloneArray(original: TArray_Of_TX): TArray_Of_TX;
var
  i: integer;
  copy: TX;
begin
  Result.SetLength(SizeOf(original));
  for i:= 0 to SizeOf(original) -1 do begin
    copy:= TX.Create;
    copy.assign(original[i]);
    Result[i]:= copy;
  end; {for i}
end;
Run Code Online (Sandbox Code Playgroud)

如果我使用TList,通用版本将是:

//code B (works, but not on a plain dynamic array)
uses
  System.SysUtils, system.classes, Generics.Collections;

type
  TMyList<T: TPersistent, constructor > = class(TList<T>)
  public
    function CloneArray: TMyList<T>;
  end;

implementation

function TMyList<T>.CloneArray: TMyList<T>;
var
  i: integer;
  temp: T;
begin
  Result:= TMyList<T>.Create;
  for i:= 0 to SizeOf(self) -1 do begin
    temp:= T.Create;
    temp.assign(self.items[i]);
    Result.Add(temp);
  end; {for i}
end;
Run Code Online (Sandbox Code Playgroud)

但是,该代码不起作用TArray<T>,因为您无法访问其Items属性,它没有.如果您使用array of ...我不知道如何使用泛型.

如何编写上面代码A的通用/泛型版本?

另见我的答案:https://stackoverflow.com/a/23446648/650492 我的答案在这里:https://stackoverflow.com/a/23447527/650492

Ste*_*nke 8

type
  TArray = class
    class function Clone<T: TPersistent, constructor>(const original: array of T): TArray<T>; static;
  end;

function TArray.Clone<T>(const original: array of T): TArray<T>;
var
  i: integer;
  copy: T;
begin
  SetLength(Result, Length(original));
  for i := 0 to Length(original) - 1 do 
  begin
    copy := T.Create;
    copy.Assign(original[i]);
    Result[i] := copy;
  end;
end;
Run Code Online (Sandbox Code Playgroud)

  • 另一种选择是什么?要么传入一个回调来进行克隆,要么对某些实现Clone方法的基类有一个约束,要么实现一些具有这种方法的接口.无论如何,这不是问题的主题,而是以通用方式实现给定的例程. (2认同)
  • @Johan Assign不能代替运行构造函数.很多类需要特定的构造函数来运行.如果您的预期用例没有那么好,但这里的代码只是通用的.对于实例化,泛型实际上并没有被删除. (2认同)