Введение в TValueИсточник: delphi2010
TValue - новая структура - запись (record), определенная в RTTI.pas, она предоставляет возможность сохранять значение и информацию о типе для экземпляров любых типов. Это видно из приведенного ниже кода.Например, в следующей программе, вы можете видеть, что значение свойства TypeInfo TValue - соответствует тому, что возвращает функция TypeInfo() для этого типа. program Project10; {$APPTYPE CONSOLE} uses SysUtils, Rtti; var v : TValue; i : Integer; begin i := 10; v := I; Writeln('Address of TypeInfo on TValue :', IntToStr(Integer(v.TypeInfo))); Writeln('Address of TypeInfo on Integer:', IntToStr(Integer(TypeInfo(Integer)))); Writeln('Value of I:',I); Writeln('Value of V:',v.AsInteger); readln; end. Результат: Address of TypeInfo on TValue :4198560 Address of TypeInfo on Integer:4198560 Value of I:10 Value of V:10 Есть несколько class operator Implicit(const Value: string): TValue; class operator Implicit(Value: Integer): TValue; class operator Implicit(Value: Extended): TValue; class operator Implicit(Value: Int64): TValue; class operator Implicit(Value: TObject): TValue; class operator Implicit(Value: TClass): TValue; class operator Implicit(Value: Boolean): TValue; Для извлечения данных существует набор согласующих функций. function AsString: string; function AsInteger: Integer; function AsExtended: Extended; function AsInt64: Int64; function AsObject: TObject; function AsClass: TClass; function AsBoolean: Boolean; Хотя это может навести вас на мысли о типе Variant, преобразование одного типа к другому не происходит автоматически. program Project10; {$APPTYPE CONSOLE} uses Rtti; var v : TValue; i : Integer; begin i := 10; v := I; // Generates and Invalid Type Cast Writeln('Value of V:',v.asString); readln; end. Для того, что бы помочь вам определить, какой тип задан в TValue, у вас есть несколько свойств и функций. // in TypInfo.pas TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat, tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString, tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray, tkUString, tkClassRef, tkPointer, tkProcedure); // part of TValue in rtti.pas property Kind: TTypeKind function IsObject: Boolean; function IsType<T>: Boolean; overload; Следующий код демонстрирует, как использовать все это. program Project10; {$APPTYPE CONSOLE} uses Rtti,TypInfo; var v : TValue; i : Integer; begin i := 10; v := I; Writeln('V.Kind =',GetEnumName(TypeInfo(TTypeKind),ord(v.Kind))); Writeln('V.IsType<Integer> = ',v.IsType<Integer>); Writeln('V.IsType<TObject> = ',v.IsType<TObject>); Writeln('V.IsObject = ',v.IsObject); readln; end. Результат. V.Kind =tkInteger V.IsType<Integer> = TRUE V.IsType<TObject> = FALSE V.IsObject = FALSE TValue обладает достаточно более широким функционалом, который можно исследовать, чему я посвящу отдельную статью позднее, здесь же приведены необходимые основы для того, что бы в следующей статье перейти к TRttiMember для свойств и полей. |