Delphi2010では RTTI(Run Time Type Information:実行時型情報)機能が強化され、リフレクション機能と同様のことが実現できるようになりました。
コードは以下の通り
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs,Rtti,TypInfo, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; TTest = class public X:integer; Y:integer; published property N:integer read X; end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); var org:TTest; oorg:TObject; C:TRttiContext; ty:TRTTIType; Fields:TArray<TRttiField>; Props:TArray<TRttiProperty>; i:integer; F:TRTTIField; V:integer; val:TValue; begin org:=TTest.Create; org.X:=10; org.Y:=20; oorg:=TObject(org); C:=TRttiContext.Create(); //ty:=c.FindType(Sender.UnitName+'.'+Sender.ClassName); ty:=c.FindType(oorg.UnitName+'.'+oorg.ClassName); Fields:=ty.GetFields(); //Memo1.Lines.Add(Sender.UnitName+'.'+Sender.ClassName); Memo1.Lines.Add(oorg.UnitName+'.'+oorg.ClassName); Memo1.Lines.Add('フィールド'); for i:=0 to Length(Fields)-1 do begin Memo1.Lines.Add(Fields[i].Name); end; Memo1.Lines.Add('プロパティ'); Props := ty.GetProperties(); for i:=0 to Length(Props)-1 do begin Memo1.Lines.Add(Props[i].Name); end; // V:=40; F:=ty.GetField('X'); F.SetValue(oorg,V); Memo1.Lines.Add('X:'+IntToStr(org.X)); Memo1.Lines.Add('Y:'+IntToStr(org.Y)); end; end.
クラスをTObjectにダウンキャストし、Tobjectから、クラス名とユニット名を文字列として取得し、その文字列から、クラスのフィールド一覧とプロパティ一覧を取得しています。さらに、ダウンキャストしたTObjectとフィールド名文字列を用い、元のクラスのフィールドに値を代入しています。
この機能により、プログラム側でクラスの実際の型を知らなくても(クラスが定義されたユニットをusesしなくても)、プロパティやフィールド、メソッドにアクセスできるようになります。
実行すると、下図の結果が得られます。