1

I'm trying to iterate over a Dynamic array passed into a generic function

I'm using TValue to achive this, but i can't get the length of the array and there for I can not get the elements.

I've written a small demo project to illustrate my problem:

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.
2
  • Why do you pass nil to TValue.Make and not @Value? Commented Sep 27, 2018 at 8:08
  • It works for a static Array, thats why I used the same approach for dynamic arrays Commented Sep 27, 2018 at 8:11

1 Answer 1

4

I found the answer my self. The problem where I was using TValue.Make and not TValue.From

This will do. Way more simple compared to where I started.

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;
Sign up to request clarification or add additional context in comments.

1 Comment

In Tokyo, there is not TValue.From, just TValue.From<T>, which translates to Make(@Value, ... and that's exactly what Sebastian Proske suggested.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.