Jump to content
egnew

Get Class Properties by ClassName

Recommended Posts

I have a procedure that loads the properties of a class into a memo:

procedure TForm1.GetProperties (p_Class: TClass);
var
  v_Context: TRttiContext;
  v_Type: TRttiType;
  v_Property: TRttiProperty;
begin
  v_Type := v_Context.GetType(p_Class);
  for v_Property in v_Type.GetProperties do
    Memo1.Lines.Add(v_Property.ToString);
end;

Sample Usage

    GetProperties(TFDPhysPGConnectionDefParams);

 

I would like a procedure to get the properties by class name instead of a class.

procedure TForm1.GetPropertiesByClassName (p_ClassName: String); // Changed
var
  v_Class: TClass;                                               // Added
  v_Context: TRttiContext;
  v_Type: TRttiType;
  v_Property: TRttiProperty;
begin
  v_Class := GetClass(p_ClassName);                             // Access Violation Exception
  v_Type := v_Context.GetType(v_Class);
  for v_Property in v_Type.GetProperties do
    Memo1.Lines.Add(v_Property.ToString);
end;

Sample Usage:

  v_FDConnection := TFDConnection.Create(nil);
  try
    v_FDConnection.DriverName := 'PG';
    GetPropertiesByClassName(v_FDConnection.Params.ClassName);
  finally
    v_FDConnection.Free;
  end;

My attempt as shown above results in a runtime exception for Access Violation.

How can I get this to work?

Share this post


Link to post
58 minutes ago, egnew said:

I would like a procedure to get the properties by class name instead of a class.

Why not use the ClassType instead of the ClassName?

GetProperties(v_FDConnection.Params.ClassType);
58 minutes ago, egnew said:

My attempt as shown above results in a runtime exception for Access Violation.

GetClass() only returns classes that are registered with RegisterClass().  Not all classes are registered.

 

GetClass() returns nil if it can't find the requested class.  You are not handling that possibility.  You can't pass nil to TRTTIContext.GetType().

 

FindClass(), on the other hand, will raise an EClassNotFound exception if the requested class is not found.

Edited by Remy Lebeau
  • Like 1

Share this post


Link to post

I added a function FIndClassByName and was able to get it to work.

function TForm1.FindClassByName (const p_ClassName: string): TClass;
var
  v_Context: TRttiContext;
  v_Type: TRttiType;
  v_TypeList: TArray<TRttiType>;
begin
  Result := nil;
  v_Context := TRttiContext.Create;
  try
    v_TypeList := v_Context.GetTypes;
    for v_Type in v_TypeList do
    begin
      if v_Type.Name = p_ClassName then
        begin
          Result := v_Type.AsInstance.MetaClassType;
          BREAK;
        end;
    end;
  finally
    v_Context.Free;
  end;
end;

procedure TForm1.GetPropertiesByClassName (p_ClassName: String);
var
  v_Class: TClass;
  v_Context: TRttiContext;
  v_Type: TRttiType;
  v_Property: TRttiProperty;
begin
  Memo1.Lines.Add('----- Properties -----');
  v_Class := FindClassByName(p_ClassName);
  if v_Class <> nil then
    begin
      v_Type := v_Context.GetType(v_Class);
      for v_Property in v_Type.GetProperties do
        Memo1.Lines.Add(v_Property.ToString);
    end;
end;

The FindClassByName function processes a lot of types to get to the one that is needed.  Please let me know if there is a better or more efficient way to do this.

 

Share this post


Link to post
18 minutes ago, Remy Lebeau said:

Why not use the ClassType instead of the ClassName?

Remy:

 

That is what I needed.  It works perfectly.

 

Thanks

 

procedure TForm1.GetPropertiesByClassType (p_Class: TClass);
var
  v_Context: TRttiContext;
  v_Type: TRttiType;
  v_Property: TRttiProperty;
begin
  Memo1.Lines.Add('----- Properties -----');
  v_Type := v_Context.GetType(p_Class);
  for v_Property in v_Type.GetProperties do
    Memo1.Lines.Add(v_Property.ToString);
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×