RTTI (Runtime Type Information) has had a major overhaul in Delphi 2010. RTTI is a central piece on which the Delphi IDE is written, and as such has been around since the first release, however I’ve heard from a number of people over the years that they’d tried to use RTTI and found it too difficult and arcane, especially compared to the Reflection API’s in Java and .NET. That’s a real shame, as the ability to write code to query the details of other objects, without knowing the type up-front, is really powerful.
However, I think that complaint will be a thing of the past with this new API. It’s been not only extended to make it more capable, it is also now much more approachable and easy to use.
One of the new features that I’m very excited about is support for Attributes in Win32. I’m working on a larger example, but here’s a quick run through of creating and then querying custom attributes.
Custom attributes are simply classes that descend from TCustomAttribute. They can have properties, methods, etc, like any other class:
MyAttribute = class(TCustomAttribute) private FName: string; FAge: Integer; public constructor Create(const Name : string; Age : Integer); property Name : string read FName write FName; property Age : Integer read FAge write FAge; end;
No real surprises here, and the constructor is implemented exactly as you’d expect.
Next, we can apply our attribute to our class:
TMyClass = class public [MyAttribute('Malcolm', 39)] procedure MyProc(const s : string); [MyAttribute('Julie', 37)] procedure MyOtherProc; end;
Here I’ve applied it to both methods, but note I’ve supplied different parameters to the Attribute. Also note the order of the parameters matches the order in the constructor. This is not just limited to methods, you can apply attributes to properties, entire classes, all sorts of things.
Of course, there’s no point adding attributes if you can’t read them from somewhere, so here’s some sample code that uses the new RTTI API to query for our attributes, and display the details in a listbox:
procedure TForm3.Button1Click(Sender: TObject); var ctx : TRttiContext; t : TRttiType; m : TRttiMethod; a : TCustomAttribute; begin ListBox1.Clear; ctx := TRttiContext.Create; try t := ctx.GetType(TMyClass); for m in t.GetMethods do for a in m.GetAttributes do if a is MyAttribute then ListBox1.Items.Add(Format('Method = %s; Attribute = %s, Name = %s, Age = %d', [m.Name, a.ClassName, MyAttribute(a).Name, MyAttribute(a).Age])); finally ctx.Free; end; end;
First I grab a reference to the RTTI Context, and load it with the ClassType of my class. I then do a for..in over the methods in my class, and for each method do a for..in over the attributes. Then I check if the attribute is my custom attribute, and if so, grab the values of Name and Age and show them in a list box.
As I mentioned earlier, I’m working on another example which is a little more useful, but hopefully this gives you a little taste of some of the new stuff coming in 2010. Also, don’t forget to watch the preview videos at http://www.embarcadero.com/rad-studio-2010/, and subscribe to get notified when new ones are published.