RTTI information starts with the TRttiMember which provides 4 bits of information about each Member.
- The name
- Visibility (private,protected,public,published)
- The type that the member is associated with
- Attributes associated with that member
This example code shows how to access each of these.
program Project4;
{$APPTYPE CONSOLE}
uses
SysUtils, Rtti, TypInfo;
type
TTest = class(TCustomAttribute)
end;
TBook = class(TObject)
private
FTitle: String;
public
[TTest]
property Title : String read FTitle write FTitle;
end;
var
c : TRttiContext;
m : TRttiMember;
{ TExample }
begin
c := TRttiContext.Create;
m := c.GetType(TBook).GetProperty('Title');
Writeln('Name:',m.Name);
Writeln('Visibility:',GetEnumName(TypeInfo(TMemberVisibility),ord(m.Visibility)));
WriteLn('Parent:',m.Parent.ToString);
Writeln('First Attribute:',m.GetAttributes[0].ToString);
writeln;
m := c.GetType(TBook).GetField('FTitle');
WriteLn('Name:',m.Name);
WriteLn('Visibility:',GetEnumName(TypeInfo(TMemberVisibility),ord(m.Visibility)));
WriteLn('Parent:',m.Parent.ToString);
readln;
c.Free;
end.
Output:
Name:Title
Visibility:mvPublic
Parent:TBook
First Attribute:TTest
Name:FTitle
Visibility:mvPrivate
Parent:TBook
The two basic TRttiMember descendants I want to cover in this blog post is TRttiField and TRttiPropery. Both descendants allow you to get and set the values on an Instance of the given type. They both provide SetValue() and GetValue() methods.
The following code demonstrates how to use both. If you missed my Introduction to TValue
I suggest you take some time to read it as it explains some of the "Magic" behind what is going on here.
program Project10;
{$APPTYPE CONSOLE}
uses
SysUtils, Rtti, TypInfo;
type
TBook = class(TObject)
private
FTitle: String;
public
property Title : String read FTitle write FTitle;
end;
var
c : TRttiContext;
p : TRttiProperty;
f : TRttiField;
book : TBook;
v : TValue;
begin
book := TBook.Create;
try
c := TRttiContext.Create;
p := c.GetType(TBook).GetProperty('Title');
p.SetValue(Book,'Go, Dog, Go!');
v := p.GetValue(Book);
Writeln('Title:',v.ToString);
f := c.GetType(TBook).GetField('FTitle');
f.SetValue(Book,'Green Eggs and Ham');
v := f.GetValue(Book);
Writeln('FTitle:',v.ToString);
readln;
c.Free;
finally
Book.Free;
end;
end.
Output:
Title:Go, Dog, Go!
FTitle:Green Eggs and Ham
With Properties you have to worry about if they are readable or writable, as attempting to call SetValue on a property that is not writable will produce an EPropReadOnly Exception. TRttiProperty has two properties "isReadable" and 'isWritable" that allow you to discover how the property was declared. The following code demonstrates how it works.
program Project10;
{$APPTYPE CONSOLE}
uses
SysUtils, Rtti, TypInfo;
type
TBook = class(TObject)
private
FTitle: String;
FUgly: String;
FAuthor: String;
public
property Title : String read FTitle write FTitle;
property Author : String read FAuthor;
property Ugly : String write FUgly;
end;
var
c : TRttiContext;
p : TRttiProperty;
begin
c := TRttiContext.Create;
try
p := c.GetType(TBook).GetProperty('Title');
WriteLn('Name:',p.Name);
Writeln('IsReadable:',p.IsReadable);
Writeln('IsWritable:',p.IsWritable);
writeln;
p := c.GetType(TBook).GetProperty('Author');
WriteLn('Name:',p.Name);
Writeln('IsReadable:',p.IsReadable);
Writeln('IsWritable:',p.IsWritable);
writeln;
p := c.GetType(TBook).GetProperty('Ugly');
WriteLn('Name:',p.Name);
Writeln('IsReadable:',p.IsReadable);
Writeln('IsWritable:',p.IsWritable);
readln;
finally
c.Free;
end;
end.
Output:
Name:Title
IsReadable:TRUE
IsWritable:TRUE
Name:Author
IsReadable:TRUE
IsWritable:FALSE
Name:Ugly
IsReadable:FALSE
IsWritable:TRUE
That pretty much wraps it up for TRttiField and TRttiProperty, in the next
post I will cover TRttiMethod.
RTTI Article List
Your code is not correct with regard to the documentation. The context does not have to be freed. Actually, you do not even have to call Create in order to use it. TRttiContext is a record and thus can be used without instantiating it.
ReplyDeleteI took some time to explain why I do what I do.
ReplyDeletehttp://robstechcorner.blogspot.com/2009/09/trtticontextcreate-trtticontextfree.html