Informationen für strukturierte Typen
Nach oben zu Mit RTTI arbeiten
Inhaltsverzeichnis
Strukturierte Typen in Delphi haben weit mehr zugeordnete Informationen als einfache Typen. Dieses Thema erläutert detailliert die Typinformationen für strukturierte Typen.
Statische Arrays und dynamische Arrays
Statische Arrays (oder einfach Arrays) und dynamische Arrays werden nicht von demselben RTTI-Objekt beschrieben. TRttiArrayType wird für statische Arrays und TRttiDynamicArrayType für dynamische Arrays verwendet.
TRttiArray stellt die folgenden Eigenschaften bereit:
- TotalElementCount: gibt die Gesamtanzahl der Elemente an, die von diesem Array in all seinen Dimensionen aufgenommen werden können.
- ElementType: gibt die Typinformationen für die Array-Elemente an.
- DimensionCount: gibt die Anzahl der Dimensionen an, die für dieses Array deklariert sind.
- Dimensions: ist eine indizierte Eigenschaft, die die Typinformationen für den Typ zurückgibt, mit dem die Dimension bezeichnet wird (TRttiEnumerationType oder TRttiOrdinalType).
Die Eigenschaft Dimensions gibt die Typinformationen des Typs zurück, der die Indizes für eine Dimension bereitstellt. Sehen Sie sich das folgende Beispiel an:
type
TMatrix = array [Boolean, 1 .. 10] of Integer;
var
LContext: TRttiContext;
LType: TRttiArrayType;
LDimType: TRttiOrdinalType;
LDimIndex: Integer;
begin
{ Den RTTI-Kontext ermitteln }
LContext := TRttiContext.Create;
{ Das RTTI-Objekt ermitteln }
LType := LContext.GetType(TypeInfo(TMatrix)) as TRttiArrayType;
{ Alle Dimensionen auflisten }
for LDimIndex := 0 to LType.DimensionCount - 1 do
begin
LDimType := LType.Dimensions[LDimIndex] as TRttiOrdinalType;
Writeln('Dimension ', LDimIndex, ' = [', LDimType.MinValue, '..',
LDimType.MaxValue, ']');
end;
end.
// Kein C++-Quellcode verfügbar
TRttiDynamicArray stellt die folgenden Eigenschaften bereit:
- ElementSize: gibt die Größe eines Elements im Array an.
- ElementType: gibt die Typinformationen für die Array-Elemente an.
- OleAutoVarType: gibt den OLE-Typ für die Array-Elemente an (sofern anwendbar).
- DeclaringUnitName: gibt den Namen der Unit zurück, in dem das Array deklariert wurde.
Bei dynamischen Arrays ist alles etwas einfacher, weil dynamische Arrays keine Mehrfach-Dimensionen zulassen und keine vordefinierte Größe haben.
Klassen, Interfaces und Records
Strukturierte Typen, wie Klassen, Records und Interfaces verfügen neben den normalen Typinformationen über zusätzliche Informationen für ihre Member. Abhängig vom eigentlichen Typ werden einige Funktionen unterstützt, andere dagegen nicht:
Typ/Member |
Felder |
Methoden |
Eigenschaften |
Abstammung |
---|---|---|---|---|
Records |
Ja |
Ja |
Nein |
N/A |
Klassen |
Ja |
Ja |
Ja |
Ja |
Interfaces |
N/A |
Ja |
N/A |
Ja |
Klassentypen werden von TRttiInstanceType-RTTI-Objekten, Record-Typen von TRttiRecordType-Objekten und Interfaces von TRttiInterfaceType-Objekten repräsentiert.
Bitte beachten Sie, dass - während nur diese drei Typen Methoden, Felder und Interfaces unterstützen -, sich die eigentlichen Methoden und Eigenschaften, die den Zugriff auf diese Typinformationen zulassen, in TRttiType befinden. Dies wurde so festgelegt, um den Abfragevorgang zu erleichtern. Die folgende Tabelle führt die wichtigsten Methoden und Eigenschaften auf, die mit diesen strukturierten Typen verwendet werden können:
Methoden |
Beschreibung |
Records |
Klassen |
Interfaces |
---|---|---|---|---|
Gibt ein bestimmtes Feld anhand des Namens zurück. |
Ja |
Ja |
Nein | |
Gibt eine Liste aller (oder nur der deklarierten) Felder des Typs zurück. |
Ja |
Ja |
Nein | |
Gibt eine bestimmte Methode anhand des Namens zurück. |
Nein |
Ja |
Ja | |
Gibt eine Liste aller (oder nur der deklarierten) Methoden des Typs zurück. |
Nein |
Ja |
Ja | |
Gibt eine bestimmte Eigenschaft anhand des Namens zurück. |
Nein |
Ja |
Nein | |
Gibt eine Liste aller (oder nur der deklarierten) Eigenschaften des Typs zurück. |
Nein |
Ja |
Nein | |
Gibt die Vorfahrklasse oder das Vorfahr-Interface zurück. |
Nein |
Ja |
Ja |
Das folgende Beispiel zeigt den Unterschied zwischen dem Ermitteln aller oder nur der deklarierten Member:
var
LContext: TRttiContext;
LClass: TRttiInstanceType;
LNewMethods, LNewFields, LNewProperties: Integer;
begin
{ Den RTTI-Kontext ermitteln }
LContext := TRttiContext.Create();
{ Typinformationen für TStringList ermitteln }
LClass := LContext.GetType(TStringList) as TRttiInstanceType;
{ Die Anzahl der neuen Methoden, Felder und Eigenschaften ermitteln, die in TStringList eingeführt wurden }
LNewMethods := Length(LClass.GetMethods()) -
Length(LClass.GetDeclaredMethods());
LNewProperties := Length(LClass.GetProperties()) -
Length(LClass.GetDeclaredProperties());
LNewFields := Length(LClass.GetFields()) -
Length(LClass.GetDeclaredFields());
{ Das Ergebnis in der Konsole ausgeben }
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[]) {
// Den RTTI-Kontext ermitteln
TRttiContext *context = new TRttiContext();
// Typinformationen für TStringList ermitteln
TRttiType *type = context->GetType(__delphirtti(TStringList));
TRttiInstanceType *instanceType = dynamic_cast<TRttiInstanceType*>(type);
if (!instanceType) {
return 1; // Fehler bei der dynamischen Typumwandlung
}
// Die Anzahl der neuen Methoden, Felder und Eigenschaften ermitteln, die in TStringList eingeführt wurden
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;
// Das Ergebnis in der Konsole ausgeben
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;
}
Konsolenausgabe:
TStringList introduces 11 fields, 68 methods, and 14 properties relative to its TStrings ancestor.
Beachten Sie bitte, dass überschriebene Methoden auch als neu eingeführt gelten.