Informations des types structurés

De RAD Studio
Aller à : navigation, rechercher

Remonter à Utilisation des informations RTTI - Index

Bien plus d'informations sont associées aux types structurés de Delphi. Cette rubrique offre des informations de type détaillées pour les types structurés.

Tableaux statiques et tableaux dynamiques

Ce n'est pas le même objet RTTI qui décrit les tableaux statiques (ou simplements tableaux) et les tableaux dynamiques. TRttiArrayType est utilisé pour les tableaux statiques, tandis que TRttiDynamicArrayType est utilisé pour les tableaux dynamiques.

Les propriétés exposées par TRttiArray sont :

  • TotalElementCount, qui spécifie le nombre total d'éléments que ce tableau peut contenir sur toutes ses dimensions.
  • ElementType, qui donne les informations de type pour les éléments de tableau.
  • DimensionCount, qui spécifie le nombre de dimensions déclarées pour le tableau.
  • Dimensions, qui est une propriété indexée qui renvoie les informations de type pour le type utilisé pour indiquer la dimension (TRttiEnumerationType ou TRttiOrdinalType).

La propriété Dimensions renvoie les informations du type qui fournit les index d'une dimension. Considérons par exemple le code suivant :

type
    TMatrix = array [Boolean, 1 .. 10] of Integer;

var
    LContext: TRttiContext;
    LType: TRttiArrayType;
    LDimType: TRttiOrdinalType;
    LDimIndex: Integer;

begin
    { Obtenir le contexte RTTI }
    LContext := TRttiContext.Create;

    { Obtenir l'objet RTTI }
    LType := LContext.GetType(TypeInfo(TMatrix)) as TRttiArrayType;

    { Enumérer toutes les 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.
// Code source C++ non disponible

Les propriétés exposées par TRttiDynamicArray sont :

  • ElementSize, qui spécifie la taille d'un élément dans le tableau.
  • ElementType, qui donne des informations de type pour les éléments de tableau.
  • OleAutoVarType, qui spécifie le type OLE pour les éléments de tableau (le cas échéant).
  • DeclaringUnitName, qui renvoie le nom de l'unité où le tableau a été déclaré.

Dans le cas des tableaux dynamiques, les choses sont plus simples car les tableaux dynamiques n'acceptent pas les dimensions multiples et n'ont pas de taille prédéfinie.

Classes, interfaces et enregistrements

Les types structurés tels que les classes, les enregistrements et les interfaces transportent, avec les informations de type normales, des informations supplémentaires associées à leurs membres. Selon le type réel, certaines fonctionnalités sont supportées, tandis que d'autres ne le sont pas :

Type/Membre

Champs

Méthodes

Propriétés

Ancêtre

Enregistrements

Oui

Oui

Non

N/A

Classes

Oui

Oui

Oui

Oui

Interfaces

N/A

Oui

N/A

Oui


Les types classe sont représentés par les objets RTTI TRttiInstanceType, les types enregistrement sont représentés par les objets TRttiRecordType, tandis que les interfaces sont représentées par les objets TRttiInterfaceType.

Notez que, tandis que seuls ces trois types supportent les méthodes, les champs et les interfaces, les méthodes et les propriétés réelles permettant d'accéder à ces informations de type sont situées dans TRttiType. Cette décision a été prise pour faciliter le processus d'interrogation. Le tableau suivant liste les méthodes et les propriétés les plus importantes qui peuvent être utilisées avec ces types structurés :

Méthodes

Description

Enregistrements

Classes

Interfaces

GetField

Renvoie un champ spécifique par son nom.

Oui

Oui

Non

GetFields, GetDeclaredFields

Renvoie la liste de tous les champs du type (ou seulement ceux déclarés).

Oui

Oui

Non

GetMethod

Renvoie une méthode spécifique par son nom.

Non

Oui

Oui

GetMethods, GetDeclaredMethods

Renvoie la liste de toutes les méthodes du type (ou seulement celles déclarées).

Non

Oui

Oui

GetProperty

Renvoie une propriété spécifique par son nom.

Non

Oui

Non

GetProperties, GetDeclaredProperties

Renvoie la liste de toutes les propriétés du type (ou seulement celles déclarées).

Non

Oui

Non

BaseType

Renvoie l'interface ou la classe ancêtre.

Non

Oui

Oui


L'exemple suivant illustre la différence entre l'obtention de tous les membres ou seulement ceux déclarés :

var
    LContext: TRttiContext;
    LClass: TRttiInstanceType;
    LNewMethods, LNewFields, LNewProperties: Integer;

begin
    { Obtenir le contexte RTTI }
    LContext := TRttiContext.Create();

    { Obtenir les informations de type pour TStringList }
    LClass := LContext.GetType(TStringList) as TRttiInstanceType;

    { Calculer le nombre des méthodes, champs et propriétés nouveaux, introduits dans TStringList }
    LNewMethods := Length(LClass.GetMethods()) -
      Length(LClass.GetDeclaredMethods());
    LNewProperties := Length(LClass.GetProperties()) -
      Length(LClass.GetDeclaredProperties());
    LNewFields := Length(LClass.GetFields()) -
      Length(LClass.GetDeclaredFields());

    { Imprimer le résultat sur la console }
    Writeln(Format
      ('%s introduit %d champs, %d méthodes et %d propriétés associés à son ancêtre %s',
      [LClass.Name, LNewFields, LNewMethods, LNewProperties,
      LClass.BaseType.Name]));

    LContext.Free;

end.
int _tmain(int argc, _TCHAR* argv[]) {
    // Obtenir le contexte RTTI
    TRttiContext *context = new TRttiContext();

    // Obtenir les informations de type pour TStringList
    TRttiType *type = context->GetType(__delphirtti(TStringList));
    TRttiInstanceType *instanceType = dynamic_cast<TRttiInstanceType*>(type);
    if (!instanceType) {
        return 1; // échec du transtypage dynamique
    }

    // Calculer le nombre des méthodes, champs et propriétés nouveaux, introduits dans 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;

    // Imprimer le résultat sur la console
    printf("%s introduit %d champs, %d méthodes et %d propriétés associés à son ancêtre %ls"
        , instanceType->Name.c_str(), newFields, newMethods, newProperties,
        instanceType->BaseType->Name.c_str());

    delete context;
    return 0;
}

qui imprime :

TStringList introduit 8 champs, 63 méthodes et 11 propriétés associés à son 
ancêtre TStrings.

Notez que les méthodes redéfinies sont aussi considérées comme des méthodes récemment introduites.

Voir aussi