I'm working with a class in Delphi defined as follows:
type
TMyObject = class(TObject)
constructor Create(a: string); overload; virtual;
constructor Create(b: integer); overload; virtual;
end;
I need to retrieve a list of constructors for TMyObject
using RTTI. I attempted to use the GetMethods('Create')
function of the TRttiType
instance for TMyObject
:
var
Context: TRttiContext;
RttiType: TRttiType;
Method: TRttiMethod;
begin
Context := TRttiContext.Create;
RttiType := Context.GetType(TMyObject);
for Method in RttiType.GetMethods('Create') do
begin
// Process method
end;
However, I found that GetMethods('Create')
also returns the Create method inherited from TObject
, which isn't appropriate for creating TMyObject
instances due to the additional parameters in TMyObject's constructors.
How can I use RTTI to get only the constructors of TMyObject
that are usable for creating TMyObject
instances? In other words, I want to exclude constructors inherited from TObject
or other ancestors that cannot be used to properly initialize TMyObject
. Is there a way to identify and filter out these inappropriate constructors using RTTI?
Any guidance or suggestions would be greatly appreciated.
Like you have noticed GetMethods
function in TRttiType
collects all methods in the class hierarchy.
But there is another method GetDeclaredMethods
in TRttiType
that will retrieve only methods declared in particular type and will not go down the ancestor list. However, this function does not have a parameter that will allows you to filter methods by name, so to get what you need you will need to write additional filtering function.
Something like:
function GetDeclaredMethods(AType: TRttiType; const AName: string): TArray<TRttiMethod>;
var
Methods: TArray<TRttiMethod>;
Method: TRttiMethod;
begin
SetLength(Result, 0);
Methods := AType.GetDeclaredMethods;
for Method in Methods do
begin
if Method.HasName(AName) then
begin
SetLength(Result, Length(Result) + 1);
Result[High(Result)] := Method;
end;
end;
end;
Adding methods in above function is not optimized, so you might want to optimize that part, but it is also not extremely inefficient unless you have large amount of overloaded methods with same name declared in your classes.