delphi RTTI 反射技术

[delphi] view plain copy

  1. unit Unit_main;
  2. interface
  3. uses
  4. Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  5. Dialogs, StdCtrls, TypInfo;
  6. type
  7. TForm_main = class(TForm)
  8. Button1: TButton;
  9. Memo1: TMemo;
  10. Memo2: TMemo;
  11. Button2: TButton;
  12. Button3: TButton;
  13. Button4: TButton;
  14. Button5: TButton;
  15. Button6: TButton;
  16. Button7: TButton;
  17. Button8: TButton;
  18. Button9: TButton;
  19. Button10: TButton;
  20. Button11: TButton;
  21. Button12: TButton;
  22. Button13: TButton;
  23. procedure Button1Click(Sender: TObject);
  24. procedure Button2Click(Sender: TObject);
  25. procedure Button3Click(Sender: TObject);
  26. procedure Button4Click(Sender: TObject);
  27. procedure Button5Click(Sender: TObject);
  28. procedure Button6Click(Sender: TObject);
  29. procedure Button7Click(Sender: TObject);
  30. procedure Button8Click(Sender: TObject);
  31. procedure Button9Click(Sender: TObject);
  32. procedure Button10Click(Sender: TObject);
  33. procedure Button11Click(Sender: TObject);
  34. procedure Button12Click(Sender: TObject);
  35. procedure Button13Click(Sender: TObject);
  36. private
  37. { Private declarations }
  38. public
  39. { Public declarations }
  40. end;
  41. PTKeyDog = ^TKeyDog;
  42. TKeyDog = record
  43. id: Integer;
  44. projectname: string;
  45. city: string;
  46. letter: string;
  47. hash: string;
  48. code: string;
  49. note: string;
  50. filepath: string;
  51. userid: Integer;
  52. end;
  53. { 自定义的类 }
  54. TMyClass = class(TComponent)
  55. public
  56. procedure msg(const str: string);
  57. function Add(const a, b: Integer): Integer;
  58. end;
  59. // 编译指令 Methodinfo 是 Delphi 2009 新增的, 只有它打开了, ObjAuto 才可以获取 public 区的信息.
  60. // 这样, ObjAuto 可以获取 TClass3 的 public、published 和默认区域的信息.
  61. {$M+}
  62. {$METHODINFO ON}
  63. TClass3 = class
  64. function Fun3: string;
  65. private
  66. function Fun3Private: string;
  67. protected
  68. function Fun3Protected: string;
  69. public
  70. function Fun3Public: string;
  71. published
  72. function Fun3Published: string;
  73. end;
  74. {$METHODINFO OFF}
  75. {$M-}
  76. var
  77. Form_main: TForm_main;
  78. implementation
  79. uses
  80. Rtti, ObjAuto;
  81. {$R *.dfm}
  82. // 获取对象的 RTTI 属性与事件的函数
  83. function GetPropertyAndEventList(obj: TObject;
  84. pList, eList: TStringList): Boolean;
  85. var
  86. ClassTypeInfo: PTypeInfo; { 类的信息结构指针 }
  87. ClassDataInfo: PTypeData; { 类的数据结构指针 }
  88. propertyList: PPropList; { TPropInfo 是属性的数据结构;
  89. PPropList 是其指针;
  90. TPropList 是属性结构指针的列表数组;
  91. PPropList 是指向这个数组的指针 }
  92. num: Integer; { 记录属性的总数 }
  93. size: Integer; { 记录属性结构的大小 }
  94. i: Integer;
  95. begin
  96. ClassTypeInfo := obj.ClassInfo; { 先获取: 类的信息结构指针 }
  97. ClassDataInfo := GetTypeData(ClassTypeInfo); { 再获取: 类的数据结构指针 }
  98. num := ClassDataInfo.PropCount; { 属性总数 }
  99. size := SizeOf(TPropInfo); { 属性结构大小 }
  100. GetMem(propertyList, size * num); { 给属性数组分配内存 }
  101. GetPropInfos(ClassTypeInfo, propertyList); { 获取属性列表 }
  102. for i := 0 to num - 1 do
  103. begin
  104. if propertyList[i].PropType^.Kind = tkMethod then { 如果是事件; 事件也是属性吗, 给分出来 }
  105. eList.Add(propertyList[i].Name)
  106. else
  107. pList.Add(propertyList[i].Name);
  108. end;
  109. pList.Sort;
  110. eList.Sort; { 排序 }
  111. FreeMem(propertyList); { 释放属性数组的内存 }
  112. Result := True;
  113. end;
  114. procedure TForm_main.Button10Click(Sender: TObject);
  115. var
  116. obj: TMyClass;
  117. t: TRttiType;
  118. m1, m2: TRttiMethod;
  119. r: TValue; // TRttiMethod.Invoke 的返回类型
  120. begin
  121. t := TRttiContext.Create.GetType(TMyClass);
  122. { 获取 TMyClass 类的两个方法 }
  123. m1 := t.GetMethod(‘msg‘); { procedure }
  124. m2 := t.GetMethod(‘Add‘); { function }
  125. obj := TMyClass.Create(Self); { 调用需要依赖一个已存在的对象 }
  126. { 调用 msg 过程 }
  127. m1.Invoke(obj, [‘Delphi 2010‘]); { 将弹出信息框 }
  128. { 调用 Add 函数 }
  129. r := m2.Invoke(obj, [1, 2]); { 其返回值是个 TValue 类型的结构 }
  130. ShowMessage(IntToStr(r.AsInteger)); { 3 }
  131. obj.Free;
  132. end;
  133. procedure TForm_main.Button11Click(Sender: TObject);
  134. var
  135. obj: TMyClass;
  136. t: TRttiType;
  137. p: TRttiProperty;
  138. r: TValue;
  139. begin
  140. obj := TMyClass.Create(Self);
  141. t := TRttiContext.Create.GetType(TMyClass);
  142. p := t.GetProperty(‘Name‘); // 继承自TComponent的name
  143. r := p.GetValue(obj);
  144. ShowMessage(r.AsString); { 原来的 }
  145. p.SetValue(obj, ‘NewName‘);
  146. r := p.GetValue(obj);
  147. ShowMessage(r.AsString); { NewName }
  148. obj.Free;
  149. end;
  150. procedure TForm_main.Button12Click(Sender: TObject);
  151. var
  152. t: TRttiType;
  153. p: TRttiProperty;
  154. r: TValue;
  155. begin
  156. t := TRttiContext.Create.GetType(TButton);
  157. p := t.GetProperty(‘Align‘);
  158. p.SetValue(Button1, TValue.FromOrdinal(TypeInfo(TAlign), Ord(alLeft)));
  159. r := p.GetValue(Button1);
  160. ShowMessage(IntToStr(r.AsOrdinal)); { 3 }
  161. end;
  162. procedure TForm_main.Button13Click(Sender: TObject);
  163. var
  164. MiArr: TMethodInfoArray;
  165. Mi: PMethodInfoHeader;
  166. obj: TClass3;
  167. begin
  168. obj := TClass3.Create;
  169. MiArr := GetMethods(obj.ClassType);
  170. Memo1.Clear;
  171. for Mi in MiArr do
  172. Memo1.Lines.Add(string(Mi.Name));
  173. obj.Free;
  174. end;
  175. procedure TForm_main.Button1Click(Sender: TObject);
  176. var
  177. propertyL, EventL: TStringList;
  178. begin
  179. // 属性
  180. propertyL := TStringList.Create;
  181. // 事件
  182. EventL := TStringList.Create;
  183. Memo1.Clear;
  184. Memo2.Clear;
  185. GetPropertyAndEventList(Self, propertyL, EventL); { 调用函数, 第一个参数是对象名 }
  186. Memo1.Lines := propertyL;
  187. Memo2.Lines := EventL;
  188. propertyL.Free;
  189. EventL.Free;
  190. end;
  191. procedure TForm_main.Button2Click(Sender: TObject);
  192. var
  193. ctx: TRttiContext;
  194. t: TRttiType;
  195. begin
  196. Memo1.Clear;
  197. for t in ctx.GetTypes do
  198. Memo1.Lines.Add(t.Name);
  199. end;
  200. procedure TForm_main.Button3Click(Sender: TObject);
  201. var
  202. ctx: TRttiContext;
  203. t: TRttiType;
  204. m: TRttiMethod;
  205. begin
  206. Memo1.Clear;
  207. t := ctx.GetType(TButton);
  208. // for m in t.GetMethods do Memo1.Lines.Add(m.Name);
  209. for m in t.GetMethods do
  210. Memo1.Lines.Add(m.ToString);
  211. end;
  212. procedure TForm_main.Button4Click(Sender: TObject);
  213. var
  214. ctx: TRttiContext;
  215. t: TRttiType;
  216. p: TRttiProperty;
  217. begin
  218. Memo1.Clear;
  219. t := ctx.GetType(TButton);
  220. // for p in t.GetProperties do Memo1.Lines.Add(p.Name);
  221. for p in t.GetProperties do
  222. Memo1.Lines.Add(p.ToString);
  223. end;
  224. procedure TForm_main.Button5Click(Sender: TObject);
  225. var
  226. ctx: TRttiContext;
  227. t: TRttiType;
  228. f: TRttiField;
  229. begin
  230. Memo1.Clear;
  231. t := ctx.GetType(TButton);
  232. // for f in t.GetFields do Memo1.Lines.Add(f.Name);
  233. for f in t.GetFields do
  234. Memo1.Lines.Add(f.ToString);
  235. end;
  236. // http://my.oschina.net/hermer/blog/320075
  237. procedure TForm_main.Button6Click(Sender: TObject);
  238. var
  239. ctx: TRttiContext;
  240. t: TRttiType;
  241. ms: TArray<TRttiMethod>;
  242. ps: TArray<TRttiProperty>;
  243. fs: TArray<TRttiField>;
  244. begin
  245. Memo1.Clear;
  246. t := ctx.GetType(TButton);
  247. ms := t.GetMethods;
  248. ps := t.GetProperties;
  249. fs := t.GetFields;
  250. Memo1.Lines.Add(Format(‘%s 类共有 %d 个方法‘, [t.Name, Length(ms)]));
  251. Memo1.Lines.Add(Format(‘%s 类共有 %d 个属性‘, [t.Name, Length(ps)]));
  252. Memo1.Lines.Add(Format(‘%s 类共有 %d 个字段‘, [t.Name, Length(fs)]));
  253. end;
  254. procedure TForm_main.Button7Click(Sender: TObject);
  255. var
  256. t: TRttiRecordType;
  257. f: TRttiField;
  258. begin
  259. Memo1.Clear;
  260. t := TRttiContext.Create.GetType(TypeInfo(TPoint)).AsRecord;
  261. Memo1.Lines.Add(t.QualifiedName);
  262. Memo1.Lines.Add(Format(‘Size: %d‘, [t.TypeSize]));
  263. Memo1.Lines.Add(EmptyStr);
  264. Memo1.Lines.Add(Format(‘字段数: %d‘, [Length(t.GetFields)]));
  265. Memo1.Lines.Add(Format(‘方法数: %d‘, [Length(t.GetMethods)]));
  266. Memo1.Lines.Add(Format(‘属性数: %d‘, [Length(t.GetProperties)]));
  267. Memo1.Lines.Add(EmptyStr);
  268. Memo1.Lines.Add(‘全部字段:‘);
  269. for f in t.GetFields do
  270. Memo1.Lines.Add(f.ToString);
  271. end;
  272. procedure TForm_main.Button8Click(Sender: TObject);
  273. var
  274. t: TRttiRecordType;
  275. f: TRttiField;
  276. begin
  277. Memo1.Clear;
  278. t := TRttiContext.Create.GetType(TypeInfo(TKeyDog)).AsRecord;
  279. Memo1.Lines.Add(t.QualifiedName);
  280. Memo1.Lines.Add(Format(‘Size: %d‘, [t.TypeSize]));
  281. Memo1.Lines.Add(EmptyStr);
  282. Memo1.Lines.Add(Format(‘字段数: %d‘, [Length(t.GetFields)]));
  283. Memo1.Lines.Add(Format(‘方法数: %d‘, [Length(t.GetMethods)]));
  284. Memo1.Lines.Add(Format(‘属性数: %d‘, [Length(t.GetProperties)]));
  285. Memo1.Lines.Add(EmptyStr);
  286. Memo1.Lines.Add(‘全部字段:‘);
  287. for f in t.GetFields do
  288. Memo1.Lines.Add(f.ToString);
  289. end;
  290. procedure TForm_main.Button9Click(Sender: TObject);
  291. var
  292. t: TRttiOrdinalType;
  293. begin
  294. Memo1.Clear;
  295. // 先从类型名获取类型信息对象
  296. t := TRttiContext.Create.GetType(TypeInfo(Byte)) as TRttiOrdinalType;
  297. Memo1.Lines.Add(Format(‘%s - %s‘, [t.Name, t.QualifiedName]));
  298. Memo1.Lines.Add(Format(‘Size: %d‘, [t.TypeSize]));
  299. Memo1.Lines.Add(‘QualifiedName: ‘ + t.QualifiedName);
  300. Memo1.Lines.Add(Format(‘Min,Max: %d , %d‘, [t.MinValue, t.MaxValue]));
  301. Memo1.Lines.Add(EmptyStr); // 空字串
  302. // 可以用 AsOrdinal 方法代替前面的 as TRttiOrdinalType
  303. t := TRttiContext.Create.GetType(TypeInfo(Word)).AsOrdinal;
  304. Memo1.Lines.Add(Format(‘%s: %s‘, [t.Name, t.QualifiedName]));
  305. Memo1.Lines.Add(Format(‘Size: %d‘, [t.TypeSize]));
  306. Memo1.Lines.Add(Format(‘Min,Max: %d , %d‘, [t.MinValue, t.MaxValue]));
  307. Memo1.Lines.Add(EmptyStr);
  308. // 也可以直接强制转换
  309. t := TRttiOrdinalType(TRttiContext.Create.GetType(TypeInfo(Integer)));
  310. Memo1.Lines.Add(Format(‘%s: %s‘, [t.Name, t.QualifiedName]));
  311. Memo1.Lines.Add(Format(‘Size: %d‘, [t.TypeSize]));
  312. Memo1.Lines.Add(Format(‘Min,Max: %d , %d‘, [t.MinValue, t.MaxValue]));
  313. Memo1.Lines.Add(EmptyStr);
  314. end;
  315. { TMyClass }
  316. function TMyClass.Add(const a, b: Integer): Integer;
  317. begin
  318. Result := a + b;
  319. end;
  320. procedure TMyClass.msg(const str: string);
  321. begin
  322. MessageDlg(str, mtInformation, [mbYes], 0);
  323. end;
  324. { TClass3 }
  325. function TClass3.Fun3: string;
  326. begin
  327. Result := ‘Fun3‘;
  328. end;
  329. function TClass3.Fun3Private: string;
  330. begin
  331. Result := ‘Fun3Private‘;
  332. end;
  333. function TClass3.Fun3Protected: string;
  334. begin
  335. Result := ‘Fun3Protected‘;
  336. end;
  337. function TClass3.Fun3Public: string;
  338. begin
  339. Result := ‘Fun3Public‘;
  340. end;
  341. function TClass3.Fun3Published: string;
  342. begin
  343. Result := ‘Fun3Published‘;
  344. end;
  345. end.

http://blog.csdn.net/earbao/article/details/46729785

时间: 2024-08-11 01:19:58

delphi RTTI 反射技术的相关文章

强大的DELPHI RTTI–兼谈需要了解多种开发语言

一月 27th, 2005 by 猛禽 风焱在<“18般武艺”?>中说到他碰上的被多种语言纠缠的问题.我在回复里说: 很多语言只要能看懂几分就行了,没必要每一种都精通 但是如果只会很少的一两种语言也是不行的. 因为看了一些关于JAVA的反射技术的应用,忽然想到DELPHI的RTTI也很强,于是试着拿数据集下手,用RTTI来实现它的对象化.用了两个晚上时间就搞定了(要不是因为开始时搞错对象–基类用了TObject,其实应该是用TPersistent才对),果然很简单. 假设有一个ADODataS

减小Delphi2010程序的尺寸(关闭RTTI反射机制)

自从Delphi2010增强了RTTI反射机制后,编译出来的程序变得更大了,这是因为默认情况下 Delphi2010 给所有类都加上了RTTI信息(呵呵,不管你用不用它,好像实用价值确实不高,至少目前我不会去用的).虽说对程序的运行速度影响不大,但会增加安装程序的大小,这也是我们不愿看到的.有没有办法禁用RTTI信息,从而减小编译后程序的大小呢?,从文档中我们找到了方法. 一.在工程中用编译指令禁用RTTI 禁用的方法很简单,就是要在工程(dpr文件中.Delphi2010下项目文件是dproj

Java中类加载机制和反射技术

我们知道一个对象在运行时有两种类型,一个是编译类型,一个是运行时类型.在程序运行时,往往是需要发现类和对象的真实的信息的.那么如何获的这种信息呢? 其一,如果我们在编译和运行时都知道类型的具体信息,这时是可以手动将一个对象转换为运行时的类型. 其二,如果我们在编译时无法预知对象和类到底是属于哪些类,那么程序只有依靠运行时的信息来发现对象和类的真实的信息了,这时就必须要用到反射技术. 在谈具体的发射技术之前,我想先回顾下,有关类的加载的一些基本的性质和原理,以方便我们更好地理解,反射的作用和特点.

7. 反射技术:其实就是动态加载一个指定的类

反射技术:其实就是动态加载一个指定的类,并获取该类中的所有的内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员.简单说:反射技术可以对一个类进行解剖. 反射的好处:大大的增强了程序的扩展性. 反射的基本步骤: 1.获得Class对象,就是获取到指定的名称的字节码文件对象. 2.实例化对象,获得类的属性.方法或构造函数. 3.访问属性.调用方法.调用构造函数创建对象. 获取这个Class对象,有三种方式: 1:通过每个对象都具备的方法getClass来获取.

Delphi知识点与技术概述【第二章 核心类库】

第三章 核心类库 Delhpi可视化编程依赖于庞大的巨型类库.Delphi 标准类库包含了数百个类以及数以千计的方法. 内容提要: *RTL包.CLX与VCL CLX用作linux中,VCL用作Windows中 VCL是一个独立的大型库(组件,控件,非可视组件,数据集合,数据感应控件,等等). 库的核心非可视化组件与类属于RTL包. Vcl结构: CLX结构: BaseCLX VisualCLX DateCLX NetCLX 库的VCL专用部分: VCL还提供了Windows专用的: Delph

C#反射技术概念作用和要点

反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的名称.限定符和参数等.有了反射,即可对每一个类型了如指掌.如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道. 1..NET可执行应用程序结构 程序代码在编译后生成可执行的应用,我们首先要了解这种可执行应用程序的结构. 应用程序结构分为应用程序域—程序集—模块—类型—成员

Java反射技术学习总结

-------<a href="http://www.itheima.com/"">android培训</a>.<a href="http://www.itheima.com/" ">java培训</a>期待与您交流!---------- Java反射技术就是将java中的类的各个组成部分反射出来变为java中相应的数据类型获得. Java同样将类中的各个组成部分进行封装,变为一个个Java类. C

反射技术

反射技术:其实就是动态加载一个指定的类,并获取该类中的所有的内容.而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员.简单说:反射技术可以对一个类进行解剖. 反射的好处:大大的增强了程序的扩展性. 反射的基本步骤: 1.获得Class对象,就是获取到指定的名称的字节码文件对象. 2.实例化对象,获得类的属性.方法或构造函数. 3.访问属性.调用方法.调用构造函数创建对象. 获取这个Class对象,有三种方式: 1:通过每个对象都具备的方法getClass来获取.

Android中Java反射技术的使用示例

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import android.os.Bundle; import android.app.Activity; /** * Demo描述: * Android中Java反射技术的使用示例 * 在Java中描述字节码文件(xxx.class)的类叫Class * 反射的过程可视为剖析Class的过