tags:

views:

53

answers:

1

I have problems in a following code:

program Project4;

{$APPTYPE CONSOLE}

uses
  SysUtils, RTTI;

type

  TRecord2 = record
    c: integer;
    d: integer;
  end;

  TClass1 = class
  public
    FRecord: record
      a: integer;
      b: integer;
    end;
    FRecord2: TRecord2;
    FPointRecord3: ^TRecord2;

    constructor Create;
  end;

constructor TClass1.Create;
begin
  FPointRecord3 := nil;
end;

var
  lContext: TRttiContext;
  lType: TRttiType;
  lFields: TArray<TRttiField>;
  i: integer;
begin
  try
    { TODO -oUser -cConsole Main : Insert code here }
    lContext := TRttiContext.Create;

    lType := lContext.GetType(TClass1);

    lFields := lType.GetFields;
    for i := 0 to Length(lFields) - 1 do
    begin
      write('Name = '+lFields[i].Name+', ');
      if lFields[i].FieldType <> nil then
        writeln('Type = '+lFields[i].FieldType.ToString)
      else
        writeln('Type = NIL!!!');
    end;
    lContext.Free;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Output:

Name = FRecord, Type = :TClass1.:1
Name = FRecord2, Type = TRecord2
Name = FPointRecord3, Type = NIL!!!

lFields[i].FieldType return NIL How get type Pointer type fields with RTTI?

+2  A: 

It doesn't create any type info because you never actually defined a type for it. You simply defined a field as a pointer to a defined type, so the compiler creates an ad-hoc "type" for it on the fly, but no RTTI.

If you want it work, do it like this:

type

  TRecord2 = record
    c: integer;
    d: integer;
  end;
  PRecord2 = ^TRecord2;

  TClass1 = class
  public
    FRecord: record
      a: integer;
      b: integer;
    end;
    FRecord2: TRecord2;
    FPointRecord3: PRecord2;

    constructor Create;
  end;
Mason Wheeler
I had the same code just 2 seconds behind you :-)
Robert Love
Thank you. It works.
Mielofon