2

Please, help me.

I looked for exists questions and no found how i can get all published property of items (declared as Class) in dynamic array in delphi class (i use Delphi 7 IDE (i can't use other version))

I have this code:

  TObjectList = array of TObject;
  TSubClass = class(TObject)
  private
    FFirstName: string;
    FLastName: string;
    FDOB: TDateTime;
    FArray : TObjectList;
  published
    property FirstName: string read FFirstName write FFirstName;
    property LastName: string read FLastName write FLastName;
    property DOB: TDateTime read FDOB write FDOB;
    property MyArray : TObjectList read FArray write FArray ;
  end;

  TListSubClass = array of TSubClass;

  TPersonList = class(TObject)
  private
    FSubClasses: TListSubClass;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property SubClasses: TListSubClass read FSubClasses write FSubClasses;
  end;

I have link to Elem of TPersonList class (MyVariable : TPersonList).

How i can using RTTI get all published property's data of my FSubClasses and FArray array items?

How i can set new data to FSubClasses using RTTI?

Thank you, Sergey.

2 Answers 2

2

What you call "dynamic array" is not what is called a "dynamic array" in the Delphi world. A "dynamic array" is defined as MyVar: array of integer for instance. In your classes, you've only TList descendants. These TList descendants are some kind of dynamic storage, but it's called a TList (or TObjectList), instead of "dynamic array".

So just use the TypInfo unit.

  • GetPropList will get you the list of all properties.
  • Then call GetObjectProp for every PPropInfo item which maps a class, and retrieve the instance of every property.
  • Call GetStrProp to retrieve the content of a string published property;
  • Call GetOrdProp to retrieve the content of an integer published property.
  • Call GetFloatProp to get a floating point value, like a TDateTime.

In case of a class published property, after having called GetObjectProp, check the returned instance type, and enumerate its content, according to its class (TObjectList or TListSubClass).

It's such a method we use in our Open Source ORM (we've dedicated some object-oriented classes for properties access, so we don't need the typinfo unit). See http://synopse.info/fossil/finfo?name=SQLite3/SQLite3Commons.pas

Sign up to request clarification or add additional context in comments.

5 Comments

Actually he does not use TList, look again at the type declarations they are indeed dynamic arrays.
Indeed! So you just have to use GetDynArrayProp and cast the returned pointer into your TObjectList type, in order to access to it like a regular dynamic array: for i := 0 to high(TObjectList(aPointer)) do ... TObjectList(aPointer)[0] ...
Thank you for answer. And how i should do to save array into property? Because when i wrote SetDynArrayProp(MyVariable, 'SubClasses', PointerToNewArrayWithNewLenght); i have in Property array first item only :( why?
how to you code "PointerToNewArrayWithNewLenght" ? You have to use pointer(NewArrayVar) and not @NewArrayVar, as far as I can guess. pointer() will retrieve the whole pointer to the dynamic array, whereas @ will retrieve the pointer to the first item of the array. You can see the difference if you use Alt-F2 during debugging to disassemble the generated code.
I not use @ operator. The problem was to use features Delphi 7. I compared the code for the last Delphi and Delphi 7. copied from 2010 that I need a function and it worked:). That is, I rewrote the code SetDynArrayProp. :)
1

Have a look at GetDynArrayProp and GetPropList of unit TypInfo.

GetDynArrayProp returns a pointer to the underlying array, you can then cast it to the correct array type.

GetPropList returns a pointer to an array of property information to all properties of the class you pass in.

The TPropInfo record that you get back from GetPropList has information on the address of the getter and setter methods associated with a property, you can use them to call the getter or setter respectively.

In general you should have a deeper look on the TypInfo unit in your Delphi help or at the online documentation:

http://docwiki.embarcadero.com/VCL/en/TypInfo

7 Comments

Thank you for answer, but when i get items of array by this way, why items haven't classinfo information? This property is nil.
What do you mean with "haven't classinfo information", could you please edit your question with the code you have tried so far?
I mean what when i get array form GetDynArrayProp items don't include classInfo information. After my research i found solution of part where i needed of get item's properties. GetDynArrayProp - works, if my Parent of the class is TPersistent. PS Sorry for my English - i am student yet ^_^"
If you want to use RTTI (i.e. published properties type information), the parent class has to have been declared with RTTI on (before Delphi 2010). That is the case for TPersistent, but not for the TObject type. You can force this by using the {$M+} conditional before the type declaration of the class, and {$M-} after it.
@Dr. Serg: It would be much easier if you could use a TList or TObjectList or a descendent of one of them as A.Bouchez suggests. Using pointers is much more error prone. It would also be useful if you edited your question to include your current state of code.
|

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.