简单测试运行时类信息(RTTI),附详细例子
新建一个单元文件,填写如下代码,然后保存为 ClassInfoUnit.pas,这里定义了一个结构,用来读取指定类的信息。
- unit ClassInfoUnit;
- interface
- uses
- Classes, TypInfo;
- type
- { 存放类属性的动态数组 }
- PropInfoArray = array of PPropInfo;
- { 用法:首先声明该结构的变量,然后通过 Create 函数或 Target 属性指定要获取 }
- { 信息的类,然后就可以通过 public 中的属性或方法来获取该类的各种信息了 }
- TClassInfo = record { use TypInfo }
- private
- { 属性:要获取其运行时信息(RTTI)的类 }
- FTarget: TClass;
- { 属性:指向存放类信息的指针 }
- FTypeInfo: PTypeInfo;
- { 属性:指向存放类数据的指针 }
- FDataInfo: PTypeData;
- { 类属性(property)的个数 }
- FPropertyCount: Cardinal;
- { 类属性列表(数组) }
- FPropertyList: PropInfoArray;
- { 设置 FTarget }
- procedure SetTarget(aClass: TClass);
- { 读取 PropertyTypes[Index] }
- function GetPropTypes(Index: Integer): PTypeInfo;
- public
- { 构造函数,用来设置要获取其信息的对象 }
- procedure Create(aObj: TObject); overload;
- { 构造函数,用来设置要获取其信息的类 }
- procedure Create(aClass: TClass); overload;
- { 获取类的所有属性和事件 }
- function GetAllProperties: string;
- { 获取类的所有属性 }
- function GetPropList: string;
- { 获取类的所有事件 }
- function GetMethodList: string;
- { 指向类信息的指针 }
- property TypeInfo: PTypeInfo read FTypeInfo;
- { 指向类数据的指针 }
- property DataInfo: PTypeData read FDataInfo;
- { 属性:要获取其运行时信息(RTTI)的类 }
- property Target: TClass read FTarget write SetTarget;
- { 类的所有属性信息列表 }
- property PropertyList: PropInfoArray read FPropertyList;
- { 类的所有属性类型列表 }
- property PropertyTypes[Index: Integer]: PTypeInfo read GetPropTypes;
- { 类的属性总个数 }
- property PropertyCount: Cardinal read FPropertyCount;
- end;
- implementation
- { 构造函数 }
- procedure TClassInfo.Create(aObj: TObject);
- begin
- if aObj = nil then
- Create(nil)
- else
- Create(aObj.ClassType);
- end;
- { 构造函数 }
- procedure TClassInfo.Create(aClass: TClass);
- begin
- Target := aClass;
- end;
- { 私有:更改要操作的类 }
- procedure TClassInfo.SetTarget(aClass: TClass);
- begin
- if FTarget = aClass then
- Exit;
- FTarget := aClass;
- if Assigned(FTarget) then
- begin
- FTypeInfo := aClass.ClassInfo;
- FDataInfo := GetTypeData(FTypeInfo);
- FPropertyCount := FDataInfo.PropCount;
- SetLength(FPropertyList, FPropertyCount);
- GetPropInfos(FTypeInfo, PPropList(FPropertyList));
- end
- else
- begin
- FTypeInfo := nil;
- FDataInfo := nil;
- FPropertyCount := 0;
- SetLength(FPropertyList,0);
- end;
- end;
- { 私有:获取属性的类型信息 }
- function TClassInfo.GetPropTypes(Index: Integer): PTypeInfo;
- begin
- Result := nil;
- if FPropertyCount = 0 then
- Exit;
- Result := FPropertyList[Index].PropType^;
- end;
- { 获取所有属性和事件列表 }
- function TClassInfo.GetAllProperties: string;
- var
- I: Integer;
- Strs: TStringList;
- begin
- if FPropertyCount = 0 then
- Exit;
- Strs := TStringList.Create;
- try
- for I := 0 to PropertyCount - 1 do
- Strs.Add(PropertyList[I].Name);
- Result := Strs.Text;
- finally
- Strs.Free;
- end;
- end;
- { 获取属性列表 }
- function TClassInfo.GetPropList: string;
- var
- I: Integer;
- Strs: TStringList;
- begin
- if FPropertyCount = 0 then
- Exit;
- Strs := TStringList.Create;
- try
- for I := 0 to PropertyCount - 1 do
- begin
- if PropertyTypes[I].Kind <> tkMethod then
- Strs.Add(PropertyList[I].Name);
- end;
- Result := Strs.Text;
- finally
- Strs.Free;
- end;
- end;
- { 获取事件列表 }
- function TClassInfo.GetMethodList: string;
- var
- I: Integer;
- Strs: TStringList;
- begin
- if FPropertyCount = 0 then
- Exit;
- Strs := TStringList.Create;
- try
- for I := 0 to PropertyCount - 1 do
- begin
- if PropertyTypes[I].Kind = tkMethod then
- Strs.Add(PropertyList[I].Name)
- end;
- Result := Strs.Text;
- finally
- Strs.Free;
- end;
- end;
- end.
然后创建一个空白窗体,窗体上创建两个 TMemo(mmo1、mmo2)和两个 TButton(btn1、btn2),双击 btn1 和 btn2 ,使用如下代码进行测试(测试在程序运行时 TControl 和 TButton 的 published 属性和方法):
- unit Form1Unit;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, ExtCtrls;
- type
- TForm1 = class(TForm)
- mmo1: TMemo;
- mmo2: TMemo;
- btn1: TButton;
- btn2: TButton;
- procedure btn1Click(Sender: TObject);
- procedure btn2Click(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form1: TForm1;
- implementation
- {$R *.dfm}
- uses
- ClassInfoUnit;
- { 获取 TControl 的运行时信息 }
- procedure TForm1.btn1Click(Sender: TObject);
- var
- CI: TClassInfo;
- begin
- Caption := 'TControl';
- CI.Create(TControl);
- mmo1.Text := CI.GetPropList;
- mmo2.Text := CI.GetMethodList;
- end;
- { 获取 TButton 的运行时信息 }
- procedure TForm1.btn2Click(Sender: TObject);
- var
- CI: TClassInfo;
- begin
- Caption := 'TButton';
- CI.Create(TButton);
- mmo1.Text := CI.GetPropList;
- mmo2.Text := CI.GetMethodList;
- end;
- end.
http://blog.csdn.net/stevenldj/article/details/7166455
简单测试运行时类信息(RTTI),附详细例子的更多相关文章
- MFC中关于运行时类信息及动态创建对象的两个宏的意义(转)
http://blog.csdn.net/ligand/article/details/49839507 MFC运行时类信息 用途: 程序在运行时,获取对象类的信息及类的继承关系 实现: 1.定义的类 ...
- 批处理bat脚本编写(附详细例子)
批处理bat脚本编写(附详细例子) 由于在项目开发的过程中经常需要编写bat脚本,而看大牛们编写 ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization ...
- Java 序列化Serializable详解(附详细例子)
Java 序列化Serializable详解(附详细例子) 1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是 ...
- 了解运行时类型信息(RTTI)
RTTI需要引用单元TypeInfo GetPropInfo 函数用于获得属性的 RTTI 指针 PPropInfo.它有四种重载形式,后面三种重载的实现都是调用第一种形式.AKinds 参数用于限制 ...
- android开发之java JDK环境变量配置的信息代码 附详细教程。
java环境变量配置: [用户变量]class_path .;%JAVA_HOME%\lib\tools;%JAVA_HOME%\jre PATH ;%JAVA_HOME%\ ...
- 【JavaSE】运行时类型信息(RTTI、反射)
运行时类型信息使得你可以在程序运行时发现和使用类型信息.--<Think in java 4th> **** 通常我们在面向对象的程序设计中我们经常使用多态特性使得大部分代码尽可能地少了解 ...
- C++ - RTTI(RunTime Type Information)执行时类型信息 具体解释
RTTI(RunTime Type Information)执行时类型信息 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details ...
- 是否含有RTTI(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- Struts2配置问题java.lang.ClassNotFoundException: org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
方法一:右键点击项目--->build path-->configure build path-->左侧菜单栏就会看到Deployment Assembly-->右侧点击add ...
- Ajax中send方法的使用
Ajax中send方法参数的使用 一般情况下,使用Ajax提交的参数多是些简单的字符串,可以直接使用GET方法将要提交的参数写到open方法的url参数中,此时send方法的参数为null. 例如 : ...
- Thinkphp的时间判断
在做项目的过程中,非常频繁地遇到时间这个问题,像时间的比较,特定时间执行某一操作,但是现在只解决了一部分问题,先说明一下时间的判断问题. 很简单,时间,不断使date(),now(),都是字符串类型的 ...
- django note
2016-2-9 Unknown command: 'syncdb' solution: syncdb command is deprecated in django 1.7. Use the py ...
- Yahoo团队经验:网站性能优化的34条黄金法则
Yahoo团队总结的关于网站性能优化的经验,非常有参考价值.英文原文:http://developer.yahoo.com/performance/rules.html 1.尽量减少HTTP请求次数 ...
- java 多线程学习笔记
这篇文章主要是个人的学习笔记,是以例子来驱动的,加深自己对多线程的理解. 一:实现多线程的两种方法 1.继承Thread class MyThread1 extends Thread{ public ...
- Android Resource介绍和使用
1. 相关文件夹介绍 文件 取值方式 string.xml getResource().getString(resourceId)或者getResource().getText(resourceId) ...
- mysql的查询缓存
查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的 SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端 ...
- oracle 11g导入导出
数据的导入 1 将D:\daochu.dmp 中的数据导入 TEST数据库中. imp system/manager@TEST file=d:\daochu.dmp 上面可能有点问题,因为 ...
- sql获取表字段名、描述和类型
SELECT TableName = OBJECT_NAME(c.object_id), ColumnsName = c.name, Description = ex.value, ColumnTyp ...