Углубленное исследование наследников TRttiMember (ч. I), свойства и поляИсточник: delphi2010
Некоторые типы, такие как классы и записи, содержат "элементы (members)", такие как поля, свойства и методы. RTTI информация начинается с TRttiMember , который предоставляет 4 бита информации о каждом Элементе.
Этот пример кода демонстрирует, как получить доступ к каждому из них. 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(). 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. |