简单测试运行时类信息(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(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- lightoj 1030
递推,倒着递推. #include<stdio.h> #define maxn 1010 #define min(a,b) (a)>(b)?(b):(a) int main() { ...
- 1.js编程风格。 --- 编写可维护的javascript
1. 使用4个空格字符作为一个缩进层级. 2. 不省略分号. ---> 自动插入分号机制非常复杂,且难于记忆. 3. 行的长度限定于80个字符. 4. 通常在运算符换行之后,下一行会增加两个层级 ...
- js闭包陷阱问题
JavaScript是一种非常强大的函数式编程语言,可以动态创建函数对象. 由于JavaScript还支持闭包(Closure),因此,函数可以引用其作用域外的变量,非常强大. 来看看在JavaScr ...
- this指针与function变量--this究竟指向哪里?
参考文章:<深入浅出 JavaScript 中的 this> http://www.ibm.com/developerworks/cn/web/1207_wangqf_jsthis/ Ja ...
- oc swift 混编 特技
1.swift 工程新建oc文件,新建的时候提示是否桥接文件,点击yes,把swift要用的oc文件的头文件 都导入桥接文件中就OK了. 2.在swift工程中oc调用 swift文件,需要在导入名字 ...
- Asp.net MVC学习--默认程序结构、工作流程
二.MVC 默认程序结构 MVC新建好之后,会对应的出现几个包,分别是:Controller.Model.View --即MVC 其中的默认的Default.aspx文件可以方便url重写,如果不设置 ...
- ARM Cortex M3(V7-M架构)硬件启动程序 一
Cortex-m3启动代码分析笔记 启动代码文件名是STM32F10X.S,它的作用先总结下,然后再分析. 启动代码作用一般是: 1)堆和栈的初始化: 2)中断向量表定义: 3)地址重映射及中断向量表 ...
- 一款C++静态分析工具 —— CppDepend
Wrote by mutouyun. (http://darkc.at/cppdepend/) 去年6月份的时候,CppDepend的一位技术社区经理(technical community mana ...
- ICON图标文件解析
icon是一种图标格式,用于系统图标.软件图标等,这种图标扩展名为*.icon.*.ico.常见的软件或windows桌面上的那些图标一般都是ICON格式的. ICON文件格式比较简单,包含文件头段. ...
- POJ 2400 最小权匹配
吐槽:首先,这道题的输入居然是错的.要将上下两个矩阵的位置换一下才可以出样例,也就是上面那个矩阵是employee对Supervisor的打分,下面那个矩阵才是Supervisor对employee的 ...