Notice: Undefined index: HTTPS in /home/developpez/www/developpez-com/template/entete.php on line 28
Generics with Delphi 2009 Win32
Developpez.com - Delphi
X

Choisissez d'abord la catégorieensuite la rubrique :

Generics with Delphi 2009 Win32

With, as a bonus, anonymous routines and routine references

Date de publication : November 13th, 2008


IX. RTTI and generics
IX-A. Changes to the pseudo-routine TypeInfo
IX-A-1. A more general TypeInfo function
IX-B. Do generic types have RTTI?


IX. RTTI and generics

In this last chapter, I am going to give some information about what generics changed to RTTI. If you never play with RTTI, you should skip this entire chapter. It is not intended at all to be an introduction to RTTI.


IX-A. Changes to the pseudo-routine TypeInfo

RTTI always begin with the pseudo-routine TypeInfo. You may know that certain types cannot be applied to this pseudo-routine; for example, pointer types. And that, because of that, it never returns nil.

So, may we call TypeInfo on a generic type T? The question is pertinent: T might as well be a pointer type (invalid for TypeInfo) or an integer type (valid).

The answer is yes, one can call TypeInfo on a generic type. But what happens then if T results in a type that has no RTTI? Well, in this only case, TypeInfo returns nil.

To illustrate the phenomenon, here is a small class method that prints the name and the kind of type, but via generics:

type
  TRTTI = class(TObject)
  public
    class procedure PrintType<T>; static;
  end;

class procedure TRTTI.PrintType<T>;
var
  Info: PTypeInfo;
begin
  Info := TypeInfo(T); // warning ! Info may be nil here

  if Info = nil then
    WriteLn('This type has no RTTI')
  else
    WriteLn(Info.Name, #9, GetEnumName(TypeInfo(TTypeKind), Byte(Info.Kind)));
end;
				
This method is quite special, in the sense that its real parameter is actually passed as a parameterized type.

begin
  TRTTI.PrintType<Integer>;
  TRTTI.PrintType<TObject>;
  TRTTI.PrintType<Pointer>;
end;
				
Whose execution yields:

Integer  tkInteger
TObject  tkClass
This type has no RTTI
				

IX-A-1. A more general TypeInfo function

I have already regretted that TypeInfo could not be applied to any type, even for a nil reply; maybe you did as well. Then, here is a small replacement method solving the method.

type
  TRTTI = class(TObject)
  public
    class procedure PrintType<T>; static;
    class function TypeInfo<T>: PTypeInfo; static;
  end;

class function TRTTI.TypeInfo<T>: PTypeInfo;
begin
  Result := System.TypeInfo(T);
end;
					
Which you may use as:

Info := TRTTI.TypeInfo<Pointer>; // Info = nil
// instead of :
Info := TypeInfo(Pointer); // compiler error, since Pointer has no RTTI
					

IX-B. Do generic types have RTTI?

There are two questions here: do non instaciated generic types (with a non defined T parameter) have RTTI? And do instanciated generic types (where T has been replaced with an actual type, like Integer) have RTTI?

The easiest way to know it is to try ;-) You may observe, with a simple test, that only instanciated generic types. Actually, that is quite logical, since non instanciated generic types are not actual types, but type templates, and do not exist once compilation is done.

One can ask himself what name would such a type have. So:

begin
  TRTTI.PrintType<TComparison<Integer>>;
  TRTTI.PrintType<TTreeNode<Integer>>;
end;
				
Which yields:

TComparison<System.Integer>  tkInterface
TTreeNode<System.Integer>    tkClass
				
This shows that the name includes, between angle brackets, the fully qualified name of the actual type replacing the type parameter.

info You can also notice that the routine reference type TComparison<T> yields tkInterface, which proves that it is actually an interface.
That is all I wanted to say about RTTI and generics. I will not of course speak about other changes brought to RTTI in Delphi 2009 because of Unicode strings.

 
Tutoriels
Les génériques avec Delphi 2009 Win32 (English version) - également disponible en espagnol et en russe
Réaliser un plug-in comportant un composant
Construire une procédure pointant sur une méthode
Création de composants - en 4 parties
Refactoring avec Delphi 2007
Prise en main de Delphi 2005
Analyseurs syntaxiques - Leur fonctionnement par l'exemple
Créer un fichier d'aide HLP
Pourquoi un paramètre const change-t-il mystérieusement de valeur ?
Sources
SJRDUnits - Routines et classes diverses
SJRDComps - Quelques composants
Projet Sepi
Présentation
FAQ Sepi
Programmes
FunLabyrinthe - Jeu de labyrinthe très spécial et très fun
TrickTakingGame - Jeux de cartes à plis en ligne
MultiAgenda - Agenda multi-répertoires
DecodeFormulaires - Décode les formulaires
Excel --> HTML - Convertisseur de tableaux Excel en HTML
AddressLinks - Lie les adresses Internet et e-mail d'un document HTML
Vipion - Tic Tac Toe sur 4x4 cases avec jeu de l'ordinateur
BigCalc - Calculatrice de haut niveau
Espace paroissial Astérion de Watermael-Boitsfort

Valid XHTML 1.0 TransitionalValid CSS!


Notice: Undefined index: HTTPS in /home/developpez/www/developpez-com/template/pied.php on line 5

Copyright © 2008-2009 Sébastien Doeraene. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -