Frage

Ist möglich mit der RTTI bestimmen, ob ein TRttiMethod ein als overload, override oder abstract markiert ist?

Vielen Dank im Voraus.

War es hilfreich?

Lösung

Überlastung: Ich glaube nicht, dass es ein RTTI-Flag für diese, aber Sie können überprüfen, um zu sehen, ob es mehr als eine Methode mit dem gleichen Namen. Das ist nicht perfekt, aber es ist wahrscheinlich so nah wie du gehst zu erhalten.

außer Kraft setzen: Erstens, stellen Sie sicher, dass das Verfahren virtuell ist. (Oder dynamische oder Nachrichtenversand.), Dann die Vorfahren der Klasse prüft für andere Methoden mit dem gleichen Namen und VirtualIndex Eigenschaft.

Abstract: Tief in der Implementierung von rtti.pas, mit einem Bündel von Daten Flags Verfahren ist eine genannt mfAbstract, wie 1 shl 7; definiert. Es gibt keinen Code, dass Verweise diesen, aber es in der RTTI vom Compiler erzeugten implementiert wird. Wenn Sie eine TRttiMethod Referenz für das Verfahren haben, können Sie es wie folgt testen:

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

PVmtMethodExEntry in der TypInfo Einheit deklariert, so dass Sie es an die Arbeit dafür zu verwenden, benötigen.

Andere Tipps

Wenn es immer noch wichtig ... Ich überprüfe es so aus:

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;

Sie sollten ihr Augenmerk auf Linie # 10 zahlen. Virtuelle oder dynamische Methoden haben DispatchKind dkVtable und dkDynamic sind. Also, wenn Methode als abstract gekennzeichnet sind, müssen sie eine von ihnen haben. In der gleichen Zeit immer class static Methode als das Ergebnis zu vermeiden, verwende ich zweite Bedingung: not TRttiMethod.IsClassMethod

Siehe auch System.Rtti:

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

Sie können diese Aufzählung Griff an einem Ermessen.

Über „Override“: s. TStream.Seek, vielleicht werden Sie etwas Nützliches für die Sie dort finden

über „Überlast“. Die Antwort von @ Maurer-Wheeler oben sieht ziemlich gut für diesen Fall

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top