Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: RTTI and arrays in Delphi 10.1 Berlin


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Jun 16, 2016 4:31 PM Last Post By: Remy Lebeau (Te...
Graham Harris

Posts: 2
Registered: 5/13/00
RTTI and arrays in Delphi 10.1 Berlin  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 16, 2016 12:26 AM
Hi

I am writing a class that will serialise records using the new RTTI features, however I am running into problems of no RTTI information when the record is defined as:

TSomeRecordType = record
Field1: string;
Field2: array[0..10] of byte;
end;

however if I redefine the above record as:

TAByteArray = array[0..10] of byte;

TSomeRecordType = record
Field1: string;
Field2: TAByteArray;
end;

RTTI is generated for Field2.

a) Is RTTI generated in Delphi 10.1 Berlin in the first situation?
b) If not is there a way around this?

Thanks in advance

Graham Harris
Peter Below

Posts: 1,227
Registered: 12/16/99
Re: RTTI and arrays in Delphi 10.1 Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 16, 2016 10:41 AM   in response to: Graham Harris in response to: Graham Harris
Graham Harris wrote:

Hi

I am writing a class that will serialise records using the new RTTI
features, however I am running into problems of no RTTI information
when the record is defined as:

TSomeRecordType = record
Field1: string;
Field2: array[0..10] of byte;
end;

however if I redefine the above record as:

TAByteArray = array[0..10] of byte;

TSomeRecordType = record
Field1: string;
Field2: TAByteArray;
end;

RTTI is generated for Field2.

a) Is RTTI generated in Delphi 10.1 Berlin in the first situation?

I have not tested it but seriously doubt it. RTTI cannot be generated
for an anonymous type. If it has no type name, how would you ever find
it?


--
Peter Below
TeamB

Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: RTTI and arrays in Delphi 10.1 Berlin [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Jun 16, 2016 4:31 PM   in response to: Graham Harris in response to: Graham Harris
Graham wrote:

I am writing a class that will serialise records using the new RTTI
features, however I am running into problems of no RTTI information
when the record is defined as:

TSomeRecordType = record
Field1: string;
Field2: array[0..10] of byte;
end;

This is a known issue, and is actually by design (whether or not that design
is correct is another matter). RTTI stands for "Runtime **TYPE** Information",
but Field2 is not using a previously defined type, it is using an anonymous
type. instead Anonymous types do not generate RTTI.

however if I redefine the above record as:

TAByteArray = array[0..10] of byte;

TSomeRecordType = record
Field1: string;
Field2: TAByteArray;
end;

RTTI is generated for Field2.

Yes, because TAByteArray is its own type.

a) Is RTTI generated in Delphi 10.1 Berlin in the first situation?

No, or in any other version, for that matter.

b) If not is there a way around this?

You already have the simplest solution - define a new type, and then use
it where needed.

If that is not an option for you, then another solution would be to define
custom Attributes that you can use to annotate fields to describe how they
need to be serialized in the absence of native RTTI. RTTI does provide access
to attributes, even for fields that do not have RTTI for their type.

http://docwiki.embarcadero.com/RADStudio/en/Attributes_Index

For example:

type
  SerializeAsStaticArrayAttribute = class(TCustomAttribute)
  private
    FElementTypeInfo: PTypeInfo;
    FLow, FHigh: Integer;
  public
    constructor Create(const AElementTypeInfo: PTypeInfo; const ALow, AHigh: 
Integer);
    property ElementTypeInfo: PTypeInfo read FElementTypeInfo;
    property LowBound: Integer read FLow;
    property HighBound: Integer read FHigh;
  end;
 
  ...
 
  TSomeRecordType = record
    Field1: string;
    [SerializeAsStaticArray(TypeInfo(byte), 0, 10)]
    Field2: array[0..10] of byte;
  end;
 
...
 
var
  Ctx: TRttiContext;
  Typ: TRttiType;
  Field: TRttiField;
  Attr: TCustomAttribute;
begin
  Ctx := TRttiContext.Create;
  Typ := Ctx.GetType(TypeInfo(TSomeRecordType));
  for Field in Typ.GetFields do
  begin
    if Field.FieldType <> nil then
    begin
      // Field1 goes here...
      ShowMessage('serialized as: ' + Field.FieldType.ToString);
    end else
    begin
      // Field2 goes here...
      for Attr in Field.GetAttributes do
      begin
        if Attr is SerializeAsStaticArrayAttribute then
        begin
          with SerializeAsStaticArrayAttribute(Attr) do
            ShowMessage('serialized as: array[' + IntToStr(LowBound) + '..' 
+ IntToStr(HighBound) + '] of ' + ElementTypeInfo.Name);
        end else
          ShowMessage(Attr.ClassName);
      end;
    end;
  end;
end.
 


--
Remy Lebeau (TeamB)
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02