Question

Is possible using the Rtti determine if a TRttiMethod is a marked as overload,override or abstract ?

thanks in advance.

Was it helpful?

Solution

Overload: I don't think there's an RTTI flag for this, but you can check to see if there's more than one method with the same name. That's not perfect, but it's probably as close as you're going to get.

Override: First, make sure the method is virtual. (Or dynamic or message dispatch.) Then check the class's ancestors for other methods with the same name and VirtualIndex property.

Abstract: Deep in the implementation section of rtti.pas, in with a bunch of method data flags, is one called mfAbstract, defined as 1 shl 7;. There's no code that references this, but it is implemented in the RTTI generated by the compiler. When you have a TRttiMethod reference for the method, you can test it like this:

IsVirtual := PVmtMethodExEntry(method.Handle).Flags and (1 shl 7) <> 0;

PVmtMethodExEntry is declared in the TypInfo unit, so you'll need to use it for that to work.

OTHER TIPS

If it still matters... I check it this way:

1. function GetCloneProc: TRttiMethod;
2. var
3.   methods: TArray<TRttiMethod>;
4.   parameters: TArray<TRttiParameter>;
5. begin
6.   methods := BaseType.GetDeclaredMethods;
7.   for Result in methods do
8.   begin
9.     if (Result.MethodKind = mkProcedure) and (Result.Name = 'CloneTo') and
10.       (Result.DispatchKind = dkStatic) and not Result.IsClassMethod then
11.    begin
12.       parameters := Result.GetParameters;
13.       if (Length(parameters) = 1) and (parameters[0].Flags = [pfAddress]) and
14.         (parameters[0].ParamType.TypeKind = tkClass) and
15.         ((parameters[0].ParamType as TRttiInstanceType).MetaclassType = (BaseType as TRttiInstanceType).MetaclassType) then
16.         Exit;
17.     end;
18.   end;
19.   Result := nil;
20. end;

You should pay attention to line #10. Virtual or Dynamic methods have DispatchKind dkVtable and dkDynamic respectively. So if method marked as abstract it must have one of them. In the same time to avoid getting class static method as the result I use second condition: not TRttiMethod.IsClassMethod

See also System.Rtti:

TDispatchKind = (dkStatic, dkVtable, dkDynamic, dkMessage, dkInterface);

You can handle this enumeration at one's discretion.

About "override": see TStream.Seek, maybe you'll find something useful for you there.

About "overload": the answer of @mason-wheeler above looks pretty good for this case.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top