Обобщения, итерирование по динамическому массиву - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь перебрать динамический массив, переданный в универсальную функцию

Я использую TValue для достижения этой цели, но я не могу получить длину массива, и там я не могуполучить элементы.

Я написал небольшой демонстрационный проект, чтобы проиллюстрировать мою проблему:

program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils, System.TypInfo, System.Rtti;

type
  TMyEnum = (me_One, me_Two, me_Three);

  Writer = class
  public
    class procedure Write<T>(Value: T);
  end;

  { Writer }

class procedure Writer.Write<T>(Value: T);
var
  ArrayValue: TValue;
  TypeInfo: pTypeInfo;
begin
  TypeInfo := System.TypeInfo(T);

  if TypeInfo.Kind <> tkDynArray then
    exit;

  TValue.Make(nil, TypeInfo, ArrayValue);
  Writeln(ArrayValue.GetArrayLength);
//Here I have my problem ArrayValue.GetArrayLength returns 0 and not 2 
end;

var
  Enums: array of TMyEnum;
  Dummy : String;
begin
  try
    SetLength(Enums, 2);
    Enums[0] := me_One;
    Enums[1] := me_Two;

    Writer.Write(Enums);
    Readln(Dummy);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

end.

1 Ответ

0 голосов
/ 27 сентября 2018

Я нашел ответ сам.Проблема, где я использовал TValue.Make, а не TValue.From

Это подойдет.Намного проще по сравнению с тем, с чего я начал

class function Writer.WriteLine<T>(AValue: T): string;
var
  ElementValue, Value: TValue;
  i: Integer;
begin
  Value := TValue.From(AValue);
  try
    if not Value.IsArray then
      Exit('');

    if Value.GetArrayLength = 0 then
      Exit('[]');

    Result := '[';

    for i := 0 to Value.GetArrayLength - 1 do
    begin
      ElementValue := Value.GetArrayElement(i);
      Result := Result + ElementValue.ToString + ',';
    end;

    Result[Length(Result)] := ']';
  finally
    Writeln(Result);
  end;
end;
...