简单测试运行时类信息(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(运行时类型信息)是动态语言与静态语言的主要区别
运行时类型信息代表类型信息和对内存的操作能力. 运行时类型信息是运行时系统的基础. 类型信息分为编译时类型信息和运行时类型信息两种: 静态语言的类型信息只在编译时使用和保留,在可执行文件中没有类型信息 ...
随机推荐
- 关于C语言中有string类型吗?
一.问题来源 今天在VS2010平台上,尝试采用scanf() string word; scanf("%s",&word); 然后发现错误,输出采用 printf(&qu ...
- hdu4745
区间DP,这类题目还是非常常见的,可惜平时都不怎么在意.一到比赛就弱得像鸟一样,真心囧. 题目要求很简单,就是一个最长的回文子序列,输出该子序列的长度. 区间DP,最常用的一种策略(类似于数学归纳法) ...
- Struts 2的iterator标签来遍历一个含有双层List的嵌套
今天碰到一个很有意思的问题,就是需要用Struts 2的iterator标签来遍历一个含有双层List的嵌套. 首先我们从最基础的说起,用iterator标签遍历一个List. 如果Action中有一 ...
- 移动端js插件分享
分享几个移动端使用的插件,个人感觉挺不错的. 1. TouchSlide1.1 滑动的焦点图 http://pan.baidu.com/s/1i3J6bbB 2. iscroll.js 模拟滚动条 ...
- navigator.geolocation例子
navigator.geolocation例子 <html> <head> <script type="text/javascript"> fu ...
- MySQL----cluster安装
第一步.下载MySQL cluster: http://cdn.mysql.com/Downloads/MySQL-Cluster-7.4/mysql-cluster-gpl-7.4.7-linux- ...
- android开源框架和开源项目(转)
特效: http://www.androidviews.net/ http://www.theultimateandroidlibrary.com/ 常用效果: 1. https://github.c ...
- 2016 Multi-University Training Contest 2 总结
第二次多校,出师未捷身先死 欣君看了一下09题,高呼水题,迅速码好,一A. 我看了11题,发现分奇偶讨论即可,于是按思路写好,一A. 欣君搞鼓出01题的一个公式,于是我照着写,一WA.简直不可思议,发 ...
- iOS 数组里面取字典的值
NSArray *arrData = @[@"1",@"2",@"3",@"4"]; NSArray *arrKey = ...
- ReactNative遇到的一些坑
1. 如果通过一个url进行下载上传操作,这个url中包含有中文的话,一定要记得将这个url转为URLEncode编码. 如: encodeURI('http://test/有中文.doc'); 2. ...