構造化型の情報
RTTI の操作 への移動
Delphi の構造化型には単純型よりもずっと多くの情報が関連付けられています。このトピックでは、構造化型の型情報を詳しく説明します。
静的配列と動的配列
静的配列(単に配列とも呼ばれます)と動的配列では、それぞれを記述する RTTI オブジェクトが異なります。静的配列には TRttiArrayType が使用されるのに対して、動的配列には TRttiDynamicArrayType が使用されます。
TRttiArray は以下のプロパティを公開しています。
- TotalElementCount: この配列がすべての次元で保持することのできる要素数の合計を示します。
- ElementType: 配列要素の型情報を示します。
- DimensionCount: 配列に宣言された次元の数を示します。
- Dimensions: 次元を表すのに使われる型の型情報を返す、インデックスの付いたプロパティです(TRttiEnumerationType または TRttiOrdinalType)。
Dimensions プロパティは、次元のインデックスとなる型の型情報を返します。たとえば、次のコードを見てください。
type
TMatrix = array [Boolean, 1 .. 10] of Integer;
var
LContext: TRttiContext;
LType: TRttiArrayType;
LDimType: TRttiOrdinalType;
LDimIndex: Integer;
begin
{ Obtain the RTTI context }
LContext := TRttiContext.Create;
{ Obtain the RTTI object }
LType := LContext.GetType(TypeInfo(TMatrix)) as TRttiArrayType;
{ Enumerate all dimensions }
for LDimIndex := 0 to LType.DimensionCount - 1 do
begin
LDimType := LType.Dimensions[LDimIndex] as TRttiOrdinalType;
Writeln('Dimension ', LDimIndex, ' = [', LDimType.MinValue, '..',
LDimType.MaxValue, ']');
end;
end.
// C++ source code unavailable
TRttiDynamicArray は以下のプロパティを公開しています。
- ElementSize:配列内の要素のサイズを示します。
- ElementType: 配列要素の型情報を示します。
- OleAutoVarType: 配列要素の OLE 型を示します(該当する場合)。
- DeclaringUnitName: 配列が宣言されているユニットの名前を返します。
動的配列の方が単純です。動的配列は多次元にすることができず、サイズも定義されていないためです。
クラス、インターフェイス、レコード
クラスやレコードやインターフェイスといった構造化型は、通常の型情報の他に、メンバに関する情報も含んでいます。実際の型によって、機能がサポートされていたりサポートされていなかったりします。
型/メンバ |
フィールド |
メソッド |
プロパティ |
上位クラス |
---|---|---|---|---|
レコード |
○ |
○ |
× |
対象外 |
クラス |
○ |
○ |
○ |
○ |
インターフェイス |
対象外 |
○ |
対象外 |
○ |
クラス型は TRttiInstanceType RTTI オブジェクトで表現されます。レコード型は TRttiRecordType オブジェクトで、インターフェイスは TRttiInterfaceType オブジェクトで表現されます。
メソッド、フィールド、およびインターフェイスをサポートしているのはこの 3 つの型だけですが、この型情報にアクセスするための実際のメソッドやプロパティは TRttiType に含まれていることに注意してください。これは問い合わせ処理を容易にするためです。これらの構造化型で利用できる主要なメソッドおよびプロパティを次の表に示します。
メソッド |
説明 |
レコード |
クラス |
インターフェイス |
---|---|---|---|---|
指定された名前のフィールドを返します。 |
○ |
○ |
× | |
型のすべてのフィールド(または宣言されたものだけ)のリストを返します。 |
○ |
○ |
× | |
指定された名前のメソッドを返します。 |
× |
○ |
○ | |
型のすべてのメソッド(または宣言されたものだけ)のリストを返します。 |
× |
○ |
○ | |
指定された名前のプロパティを返します。 |
× |
○ |
× | |
型のすべてのプロパティ(または宣言されたものだけ)のリストを返します。 |
× |
○ |
× | |
上位クラスまたは上位インターフェイスを返します。 |
× |
○ |
○ |
次の例では、すべてのメンバを取得する場合と宣言されたメンバだけを取得する場合の違いを示します。
var
LContext: TRttiContext;
LClass: TRttiInstanceType;
LNewMethods, LNewFields, LNewProperties: Integer;
begin
{ Obtain the RTTI context }
LContext := TRttiContext.Create();
{ Obtain type information for TStringList }
LClass := LContext.GetType(TStringList) as TRttiInstanceType;
{ Calculate the number of new methods, fields, and properties introduced in TStringList }
LNewMethods := Length(LClass.GetMethods()) -
Length(LClass.GetDeclaredMethods());
LNewProperties := Length(LClass.GetProperties()) -
Length(LClass.GetDeclaredProperties());
LNewFields := Length(LClass.GetFields()) -
Length(LClass.GetDeclaredFields());
{ Print the result onto the console }
Writeln(Format
('%s introduces %d fields, %d methods, and %d properties relative to its %s ancestor',
[LClass.Name, LNewFields, LNewMethods, LNewProperties,
LClass.BaseType.Name]));
LContext.Free;
end.
int _tmain(int argc, _TCHAR* argv[]) {
// Obtain the RTTI context
TRttiContext *context = new TRttiContext();
// Obtain type information for TStringList
TRttiType *type = context->GetType(__delphirtti(TStringList));
TRttiInstanceType *instanceType = dynamic_cast<TRttiInstanceType*>(type);
if (!instanceType) {
return 1; // failure to dynamic cast
}
// Calculate the number of new methods, fields, and properties introduced in TStringList
const int newMethods = instanceType->GetMethods().Length -
instanceType->GetDeclaredMethods().Length;
const int newProperties = instanceType->GetProperties().Length -
instanceType->GetDeclaredProperties().Length;
const int newFields = instanceType->GetFields().Length -
instanceType->GetDeclaredFields().Length;
// Print the result onto the console
printf("%ls introduces %d fields, %d methods, and %d properties relative to its %ls ancestor"
, instanceType->Name.c_str(), newFields, newMethods, newProperties,
instanceType->BaseType->Name.c_str());
delete context;
return 0;
}
コンソール出力は以下のとおりです。
TStringList introduces 11 fields, 68 methods, and 14 properties relative to its TStrings ancestor.
オーバーライドされたメソッドも、新たに導入されたものとみなされることに注意してください。