Delphi 2009 的反射单元(ObjAuto):


本文整理自网络,侵删。

 
ObjAuto 单元应该算是对 TypInfo 单元的功能扩展吧? 它提供了 5 个方法:
GetMethods、GetMethodInfo、CreateMethodPointer、ReleaseMethodPointer、ObjectInvoke
通过 GetMethods、GetMethodInfo 可以获取类公用成员的详细信息.

通过 TypInfo 只能获取 published 区中成员的信息(例子);
通过 ObjAuto 也能获取 public 区的成员信息.

本例效果图:



本例有两个单元, 辅助单元(Unit2)里存放了 3 个用于测试的类:
unit Unit2;

interface

type
//TClass1 没有指定额外的编译指令, ObjAuto 只能获取其 published 区的方法
  TClass1 = class
    function Fun1: string;
  private
    function Fun1Private: string;
  protected
    function Fun1Protected: string;
  public
    function Fun1Public: string;    
  published
    function Fun1Published: string;
  end;

//TClass2 指定了 {$M+}, ObjAuto 能获取其 published 区和默认区域的方法.
//一般情况下, 默认区域的成员相当于在 public 区;
//指定了 {$M+} 以后, 默认区域的成员相当于在 published 区.
//因为 TPersistent(这是很多类的祖先) 已经指定了 {$M+}, 所以大多类的都是 {$M+} 打开的.
{$M+}
  TClass2 = class
    function Fun2: string; {默认区域}
  private
    function Fun2Private: string;
  protected
    function Fun2Protected: string;
  public
    function Fun2Public: string;    
  published
    function Fun2Published: string;
  end;
{$M-}

//编译指令 Methodinfo 是 Delphi 2009 新增的, 只有它打开了, ObjAuto 才可以获取 public 区的信息.
//这样, ObjAuto 可以获取 TClass3 的 public、published 和默认区域的信息.
{$M+}
{$METHODINFO ON}
  TClass3 = class
    function Fun3: string;
  private
    function Fun3Private: string;
  protected
    function Fun3Protected: string;
  public
    function Fun3Public: string;    
  published
    function Fun3Published: string;
  end;
{$METHODINFO OFF}
{$M-}

implementation

{ TClass1 -------------------------------------------------}

function TClass1.Fun1: string;
begin
  Result := 'Fun1';
end;

function TClass1.Fun1Private: string;
begin
  Result := 'Fun1Private';
end;

function TClass1.Fun1Protected: string;
begin
  Result := 'Fun1Protected';
end;

function TClass1.Fun1Public: string;
begin
  Result := 'Fun1Public';
end;

function TClass1.Fun1Published: string;
begin
  Result := 'Fun1Published';
end;


{ TClass2 -------------------------------------------------}

function TClass2.Fun2: string;
begin
  Result := 'Fun2';
end;

function TClass2.Fun2Private: string;
begin
  Result := 'Fun2Private';
end;

function TClass2.Fun2Protected: string;
begin
  Result := 'Fun2Protected';
end;

function TClass2.Fun2Public: string;
begin
  Result := 'Fun2Public';
end;

function TClass2.Fun2Published: string;
begin
  Result := 'Fun2Published';
end;


{ TClass3 -------------------------------------------------}

function TClass3.Fun3: string;
begin
  Result := 'Fun3';
end;

function TClass3.Fun3Private: string;
begin
  Result := 'Fun3Private';
end;

function TClass3.Fun3Protected: string;
begin
  Result := 'Fun3Protected';
end;

function TClass3.Fun3Public: string;
begin
  Result := 'Fun3Public';
end;

function TClass3.Fun3Published: string;
begin
  Result := 'Fun3Published';
end;

end.

主单元(Unit1):
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses ObjAuto, Unit2;

{获取 Unit2.TClass1 的信息}
procedure TForm1.Button1Click(Sender: TObject);
var
  MiArr: TMethodInfoArray;
  Mi: PMethodInfoHeader;
  obj: TClass1;
begin
  obj := TClass1.Create;
  MiArr := GetMethods(obj.ClassType);

  ListBox1.Clear;
  for Mi in MiArr do 
    ListBox1.Items.Add(string(Mi.Name));

  obj.Free;
end;

{获取 Unit2.TClass2 的信息}
procedure TForm1.Button2Click(Sender: TObject);
var
  MiArr: TMethodInfoArray;
  Mi: PMethodInfoHeader;
  obj: TClass2;
begin
  obj := TClass2.Create;
  MiArr := GetMethods(obj.ClassType);

  ListBox1.Clear;
  for Mi in MiArr do
    ListBox1.Items.Add(string(Mi.Name));

  obj.Free;
end;

{获取 Unit2.TClass3 的信息}
procedure TForm1.Button3Click(Sender: TObject);
var
  MiArr: TMethodInfoArray;
  Mi: PMethodInfoHeader;
  obj: TClass3;
begin
  obj := TClass3.Create;
  MiArr := GetMethods(obj.ClassType);

  ListBox1.Clear;
  for Mi in MiArr do 
    ListBox1.Items.Add(string(Mi.Name));

  obj.Free;
end;

end.

相关阅读 >>

Delphi sender 的用法举例

Delphi 之前解析串口数据

Delphi 获取邮箱中的用户名

Delphi监视注册表

Delphi多媒体函数

Delphi 完美获取硬盘id

Delphi 窗体的位置和高宽度-tform:letf、top、width、height、clientwidth、clientheight

Delphi如何在tmemo控件光标当前位置插入字符串

如何用Delphi实现windows xp中“本地连接”的启用和禁用

Delphi通过loadlibrary调用其他动态库

更多相关阅读请进入《Delphi》频道 >>



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...