2009年8月29日土曜日

Rttiを試してみるその4

以前のポストで、可視性がPrivateのメソッドは、読めないということを
記述しましたが、実際には、

自分で定義したメソッドであれば

コンパイラ指定{$RTTI EXPLICIT METHODS}で
TRttiContextのGetMehtodで列挙する可視性を制御することが可能のようです。

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

とすれば、すべての可視性の列挙が可能です。(正し、継承元のメソッドには
可視性の制御は及ばない見たいです。)

また、

{$RTTI EXPLICIT METHODS([vcPrivate])}

とすれば、Private可視性のメソッドの列挙が可能です。

以下、検証ように使ったソースです。


unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, CheckLst;

type
TForm1 = class(TForm)
Button1: TButton;
CheckListBox1: TCheckListBox;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;

var
Form1: TForm1;

implementation

uses Rtti,Typinfo,Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
ctx : TRttiContext;
rtmary : TArray;
rtm : TRttiMethod;
obj : TObject;
Args : Array of TValue;
rtp : TRttiType;
idx : Integer;
begin

ctx := TRttiContext.Create;

//自分で定義したメソッドのみを取得するには、
//GetDeclaredMethodsを使います。
rtmary := ctx.GetType(Unit2.TSakaTest).GetDeclaredMethods;
//rtmary := ctx.GetType(Unit2.TSakaTest).GetMethods();

CheckListBox1.Clear;

if rtmary <> nil then
begin
for rtm in rtmary do
begin
idx := CheckListBox1.Items.Add(rtm.Name);
if rtm.Visibility = TMemberVisibility.mvPrivate then
begin
CheckListBox1.Checked[idx] := true;
end;

end;

end;

end;

end.






unit Unit2;
interface

uses classes;

// {$RTTI EXPLICIT METHODS([vcPublished,vcPublic,vcPrivate])}
{$RTTI EXPLICIT METHODS([vcPrivate])}
Type TSakaTest = Class(TObject)
private
function SayPrivateMessage : String;
public
function SayPublicMessage : String;
End;

implementation

{ TSakaTest }

function TSakaTest.SayPrivateMessage: String;
begin
Result := 'This is a Private Method';
end;

function TSakaTest.SayPublicMessage: String;
begin
Result := 'This is a Public Method';
end;

end.

0 件のコメント: