2015-05-19 19 views
2
program Project37; 

{$APPTYPE CONSOLE} 

{$RTTI EXPLICIT METHODS([vcPrivate,vcProtected,vcPublic, vcPublished])} 

    type 
     TBar = class 
     procedure Test1; virtual; 
     end; 

     TFoo = class(TBar) 
     end; 


     procedure TBar.Test1; 
     begin 
     WriteLn(MethodName(@TBar.Test1)); //compiles, but does not show anything 
     //WriteLn(MethodName(@Self.Test1)); //does not compile 
     end; 

var 
    Foo: TBar; 

begin 
    Foo:= TFoo.Create; 
    Foo.Test1; 
    Foo.Free 
    Foo:= TBar.Create; 
    Foo.Test1; 
    Foo.Free; 
    ReadLn; 
end. 

如果我運行的程序沒有任何顯示。
如何讓MethodName實際工作?如何獲取沒有硬編碼的methodname?

我正在使用XE7,但我懷疑它在舊版本中有所不同。

+1

'MethodName'來自'System',它似乎只適用於'published'成員。我猜你最好的選擇是使用'System.Rtti'。即使那樣,我也沒有看到使用Rtti可以完成什麼:無論如何,你正在對你的'@ TBar.Test1'進行硬編碼,不是嗎?看着堆棧可能是唯一可行的選擇,而不是Rtti。 –

+0

@GünthertheBeautiful,這個問題是重構。如果我更改名稱,則字符串不會。那會很糟糕。看着堆棧需要debuginfo,我可能沒有。 – Johan

回答

5

MethodName要求發佈該方法。滿足這樣的要求:

type 
    TBar = class 
    published 
    procedure Test1; virtual; 
    end; 

如果您想獲取未發佈成員的方法名稱,請使用新樣式RTTI。像這樣:

{$APPTYPE CONSOLE} 
{$RTTI EXPLICIT METHODS([vcPrivate,vcProtected,vcPublic, vcPublished])} 

uses 
    System.Rtti; 

type 
    TBar = class 
    private 
    procedure Test1; 
    end; 

procedure TBar.Test1; 
begin 
end; 

var 
    ctx: TRttiContext; 
    Method: TRttiMethod; 

begin 
    for Method in ctx.GetType(TBar).GetMethods do 
    if [email protected] then 
     Writeln(Method.Name); 
end. 

當然,你可以把這個包成,將返回給定類型和代碼地址的方法名稱的函數。

相關問題