• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

delphiRTTI机制学习(一)

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

RTTI即运行时类型识别,用来识别动态对象的类型。即使我们仅仅有基类的指针和引用,可以识别出该指针和引用所指向那个类(基类或派生类)。RTTI会带来一定的性能开销。

一、新建一个Console工程

二、定义一个类并引用System.Rtti (我用的是XE3,2010-XE的直接用Rtti)写好后按Ctrl+Shit+G生成方法

 

三、测试一下 获取类属性(property)

 

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Rtti;

type
  TMyClass = class
    private
      FID: Integer;
      FName: String;
    protected
      procedure WriteName();
      function GetName():String;
    published
      property TestProp1:Integer read FID write FID;
      property TestProp2:String read FName write FName;
      property TestProp3:String read FName write FName;
      property TestProp4:Integer read FID write FID;

  end;

{ TMyClass }

function TMyClass.GetName: String;
begin

end;

procedure TMyClass.WriteName;
begin

end;

var
 ctx: TRttiContext;
 t: TRttiType;
 prop: TRttiProperty;

begin
 ctx := TRttiContext.Create;
 t := ctx.GetType(TMyClass);
 for prop in t.GetProperties do
 begin
   //获取属性类型
   WriteLn(prop.PropertyType.ToString());
 end;
 ctx.Free;
 ReadLn;

end.

 

如图,获取了Property的四个字段属性

 

四、测试二获取类成员(private)

var
 ctx: TRttiContext;
 t: TRttiType;
 prop: TRttiProperty;
 m: TRttiMethod;
 field: TRttiField;

begin
 ctx := TRttiContext.Create;
 t := ctx.GetType(TMyClass);
 for field in t.GetFields do
 begin
    //获取成员
   WriteLn(field.ToString());
 end;
 ctx.Free;
 ReadLn;

end.

(04 08代表地址偏移)?

 

还有更多的属性GetMethds获取方法的 自行试验吧

 

五、动态调用方法

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils, System.Rtti, System.TypInfo;

type
  TMyClass = class
    private
      FID: Integer;
      FName: String;
    public
      procedure WriteName(); overload;
      procedure AddName(const param1: String);overload;
      function GetName():String;

    published
      property TestProp1:Integer read FID write FID;
      property TestProp2:String read FName write FName;
      property TestProp3:String read FName write FName;
      property TestProp4:Integer read FID write FID;
  end;

{ TMyClass }

function TMyClass.GetName: String;
begin
  WriteLn('调用了GetName过程');
  Result := '调用成功';
end;

procedure TMyClass.AddName(const param1: String);
begin
   WriteLn('调用了带有参数的AddName方法:' + param1);
end;
procedure TMyClass.WriteName;
begin
    WriteLn('调用了WriteName方法');
end;




var
 ctx: TRttiContext;
 t: TRttiType;
 prop: TRttiProperty;
 m: TRttiMethod;
 field: TRttiField;
 r: TValue;
 cls: TMyClass;


begin
 ctx := TRttiContext.Create;
 cls := TMyClass.Create;
 try
    t := ctx.GetType(TMyClass);
    //通过传入方法名获取方法地址 只能取public方法 protected的取不到
    m := t.GetMethod('WriteName');
    m.Invoke(cls, []);

    //如果是重载方法报参数不匹配
    m := t.GetMethod('AddName');
    m.Invoke(cls, ['有参数的']);
    //调用带有返回值的
    m := t.GetMethod('GetName');

    r := m.Invoke(cls,[]);

    case r.Kind of
      tkString:
        WriteLn('返回值类型:String');
      tkUString:
        WriteLn('返回值类型:Unicode String');
    end;
    WriteLn('返回值:' + r.ToString());


 finally
    cls.Free;
    ctx.Free;
 end;

 ReadLn;

end.

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Delphi下DLL编程知识(转)发布时间:2022-07-18
下一篇:
DelphiUnabletoinvokeCodeCompletionduetoerrorsinsourcecode发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap