Domanda

I know how to manipulate the derived generic classes like TList etc.

However when I want to manipulate a plain dynamic array I run into difficulties.

How do I translate the following code into a version that uses generics?

//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;

If I was using a TList, the generic version would be:

//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;

However that code does not work for TArray<T>, because you cannot access its Items property, it has none. If you use the array of ... I don't see how you can use generics.

How do I write a general/generics version of code A above?

See also my answer here: https://stackoverflow.com/a/23446648/650492 And my answer here: https://stackoverflow.com/a/23447527/650492

È stato utile?

Soluzione

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top