Углубленное исследование наследников TRttiMember (ч. I), свойства и поля
Некоторые типы, такие как классы и записи, содержат “элементы (members)”, такие как поля, свойства и методы. RTTI информация начинается с TRttiMember , который предоставляет 4 бита информации о каждом Элементе.
- Имя;
- Область видимости (private, protected, public, published);
- Тип, с которым ассоциируется элемент;
- Атрибуты, ассоциирующиеся с этим элементом.
Этот пример кода демонстрирует, как получить доступ к каждому из них.
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.
Результат:
Name:Title Visibility:mvPublic Parent:TBook First Attribute:TTest Name:FTitle Visibility:mvPrivate Parent:TBook
Два основных наследника TRttiMember, о которых я хочу рассказать в этом посте, – TRttiField и TRttiPropery. Оба они позволяют вам получить и получать и присваивать значения экземпляров данного типа. Соответственно, они оба имеют методы SetValue() и GetValue().
Следующий код демонстрирует, как их использовать. Если вы пропустили мое Введение в TValue (перевод), то я советую вам уделить некоторое время, что прочесть его, так как это позволит объяснить то “волшебство”, которое будет дальше.
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.
Результат:
Title:Go, Dog, Go! FTitle:Green Eggs and Ham
Говоря о свойствах (Properties), вы должны проследить за тем, допускают -ли они возможность считывания и записи значения, так как попытка вызова SetValue для не изменяемого свойства вызовет исключение EPropReadOnly. TRttiProperty имеет два свойства “isReadable” и ‘isWritable”, которые позволяют вам определить, каким образом свойство было описано. Следующий код демонстрирует, как это работает.
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.
Результат:
Name:Title IsReadable:TRUE IsWritable:TRUE Name:Author IsReadable:TRUE IsWritable:FALSE Name:Ugly IsReadable:FALSE IsWritable:TRUE
Этот пост в значительной мере приоткрыл завесу над TRttiField и TRttiProperty, в следующем посте я расскажу о TRttiMethod.








