Is it possible to get the index of class property?
Asked Answered
A

2

7
type
  TMyClass = class
  ...
  public
    ...
    property P1: Integer Index 1 read GetInteger write SetInteger;
    property P2: Integer Index 2 read GetInteger write SetInteger;
    property P3: Integer Index 3 read GetInteger write SetInteger;
    ...
  end;

Is it possible to get the index of class property? For example, something like

  I := IndexOfProperty(TMyClass.P2);
Ataractic answered 31/10, 2013 at 18:0 Comment(1)
@JerryDodge - I need index of public property.Ataractic
A
6

You can use the RTTI, to get the index of a property. depending of you Delphi version you can use GetPropInfo method (only for published properties) or access such info via the TRttiInstanceProperty class

Try this sample.

{$APPTYPE CONSOLE}

uses
  Rtti,
  SysUtils,
  TypInfo;

type
  TMyClass = class
  private
    function GetInteger(const Index: Integer): Integer;
    procedure SetInteger(const Index, Value: Integer);

  public
    property P1: Integer Index 1 read GetInteger write SetInteger;
    property P2: Integer Index 2 read GetInteger write SetInteger;
    property P3: Integer Index 3 read GetInteger write SetInteger;
  end;



{ TMyClass }

function TMyClass.GetInteger(const Index: Integer): Integer;
begin

end;

procedure TMyClass.SetInteger(const Index, Value: Integer);
begin

end;


var
  LRttiInstanceProperty   : TRttiInstanceProperty;
  LRttiProperty : TRttiProperty;
  Ctx: TRttiContext;
  LPropInfo : PPropInfo;
begin
 try
   LPropInfo:= GetPropInfo(TMyClass, 'P1'); //only works for published properties.
   if Assigned(LPropInfo) then
    Writeln(Format('The index of the property %s is %d',[LPropInfo.Name, LPropInfo.Index]));


   Ctx:= TRttiContext.Create;
   try
     LRttiProperty:=  Ctx.GetType(TMyClass).GetProperty('P2');
     if Assigned(LRttiProperty) and (LRttiProperty is TRttiInstanceProperty) then     
     begin
      LRttiInstanceProperty := TRttiInstanceProperty(LRttiProperty);
      Writeln(Format('The index of the property %s is %d',[LRttiProperty.Name, LRttiInstanceProperty.Index]));
     end;
   finally
     Ctx.Free;
   end;

 except
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
Adi answered 31/10, 2013 at 19:53 Comment(4)
You don't need to create an instance of the class in order to use GetPropInfo(). You can pass the class type instead of an object pointer. Also, TRttiInstanceProperty has its own Index property, you don't need to use PropInfo.Index.Draught
You mention "(only for published properties)" but yet the example is public properties...Tantalate
@JerryDodge, I know that, The OP must modify the class and declare as published the properties in order to use the GetPropInfo function.Adi
@PRUZ - I have an additional question. Please see #19722894Ataractic
D
6

A property's RTTI contains the index. Your properties are declared as public, so they are not accessible via the older style RTTI provided by the TypInfo unit. However, they are accessible via the newer style RTTI provided by the Rtti unit (D2010 and later only):

uses
  Rtti;

var
  Ctx: TRttiContext;
  I: Integer;
begin
  Ctx := TRttiContext.Create;
  I := (Ctx.GetType(TMyClass).GetProperty('P2') as TRttiInstanceProperty).Index;
end;

Had your properties been declared as published instead, then you could use TypInfo RTTI:

uses
  TypInfo;

var
  I: Integer;
begin
  I := GetPropInfo(TMyClass, 'P2').Index;
end;
Draught answered 31/10, 2013 at 19:56 Comment(4)
But he can use $RTTI pragma to make public properties also covered for TypeInfo, can't he ?Beslobber
@Remy Lebeau - I have an additional question. Please see #19722894Ataractic
@Arioch'The - Delphi XE4, {$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished])} but GetPropInfo() does not work for public props !?Ataractic
@Ataractic if i only knew... personally i just cannot get class properties enumerated at all! stackoverflow.com/questions/19495258Beslobber

© 2022 - 2024 — McMap. All rights reserved.