IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

RegisterClasses et classes génériques


Sujet :

Langage Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Avatar de Higgins
    Inscrit en
    Juillet 2002
    Messages
    539
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 539
    Par défaut RegisterClasses et classes génériques
    Bonjour,

    Je souhaiterais savoir s'il est possible d'utiliser "RegisterClasses" avec des classes génériques.

    Je m'en sers pour instancier dynamiquement des objets à partir du nom de classe.
    Je n'ai aucun problème pour mes classes qui héritent de TPersistent , tout fonctionne bien

    En revanche, j'utilise aussi des classes génériques
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    type ClasseGenerique<T:TMaClasse, constructor>= class(TPersistent)
    que je voudrais, aussi, pouvoir instancier dynamiquement mais je n'arrive pas à les "enregistrer"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    //[dcc64 Erreur] : E2003 Identificateur non déclaré : 'T'
    registerClasses([ClasseGenerique<T>]);
     
    //idem 
    registerClasses([ClasseGenerique]);
     
    //idem
    registerClasses([ClasseGenerique<T:TMaClasse>]);
    Existe-t-il une syntaxe ou une directive particulière ou est-ce tout simplement impossible?

  2. #2
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    A ma connaissance ce n'est pas possible mais tests quand même la bonne version :

    registerClasses([ClasseGenerique<T:TMaClasse, constructor>]);

    même si je n'y crois pas trop.

  3. #3
    Membre éclairé
    Avatar de Higgins
    Inscrit en
    Juillet 2002
    Messages
    539
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 539
    Par défaut
    Citation Envoyé par pprem Voir le message
    A ma connaissance ce n'est pas possible mais tests quand même la bonne version :

    registerClasses([ClasseGenerique<T:TMaClasse, constructor>]);

    même si je n'y crois pas trop.
    Je l'ai oublié dans ma liste mais je l'avais aussi testé sans succès

  4. #4
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    RegisterClass attends un définition de classe; "ClasseGenerique<T>" n'est pas une définition de classe, c'est la définition d'un generic.

    tu pourrais par exemple appeler RegisterClass([ClasseGenerique<TButton>, ClasseGenerique<TEdit>])...encore que je ne suis pas certain du résultat vu que le className va être un peu douteux je suppose.

    dans le generic, "T" peut être un peu n'importe quoi, mais ce n'est pas un paramètre, c'est une définition générique...donc enregistrer ce type n'est pas possible
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  5. #5
    Membre éclairé
    Avatar de Higgins
    Inscrit en
    Juillet 2002
    Messages
    539
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 539
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    tu pourrais par exemple appeler RegisterClass([ClasseGenerique<TButton>, ClasseGenerique<TEdit>])...encore que je ne suis pas certain du résultat vu que le className va être un peu douteux je suppose.
    Bien vu, je n'y avais pas pensé mais..ça ne fonctionne pas à l'exécution

  6. #6
    Membre éclairé
    Avatar de Higgins
    Inscrit en
    Juillet 2002
    Messages
    539
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 539
    Par défaut
    J'avais mis le tag "Résolu" avec l'idée de laisser tomber mais comme je suis persévérant (ou borné, têtu: choisissez l'expression qui vous convient) j'ai essayé d'approfondir la suggestion de Paul (qui compilait mais générait une erreur à l'exécution)
    J'ai ajouté des classes génériques descendantes, que j'ai enregistrées avec RegisterClasses()
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    type ClasseGenerique<T:TMaClasse, constructor>= class(TPersistent)
    ....
    Type GenMaClasse1=class(Classegenerique<TMaClasse1>);
    Type GenMaClasse2=class(Classegenerique<TMaClasse2>);
    .....
    initialization
    registerClasses([GenMaClasse1,GenMaClasse2])
    ça fonctionne presque. A l'issue du code ci-dessous, lorsque j'évalue "UnObjet.classname" dans le debugger, il a bien le type TMaclasse1 ou TMaclasse2 attendu par contre, il ne passe pas dans le constructeur de ClasseGenerique<T:TMaClasse>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    var unobjet:Tpersistent;
    if choix1 then
       unObjet=getclass('TMaClasse1').create
    else
       unObjet=getclass('TMaClasse2').create;
    Du coup, j'ai modifié la déclaration de mes classes comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    type ClasseGenerique<T:TMaClasse, constructor>= class(TPersistent)
     public
         constructor Create;virtual;
    end;
    ....
    Type GenMaClasse1=class(Classegenerique<TMaClasse1>)
    public
      constuctor create;override;
    end;
     
    .....
    implementation
     
    constructor GenMaclasse1.create;
    begin
      Inherited create;
    end;
    Lors de l'exécution, le code ne passe jamais dans GenMaclasse1.create alors que la variable unObjet est bien créée avec le bon type. Est-ce que j'ai loupé quelque chose dans les déclarations?

  7. #7
    Membre Expert
    Avatar de pprem
    Homme Profil pro
    MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Inscrit en
    Juin 2013
    Messages
    1 876
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : MVP Embarcadero - formateur&développeur Delphi, PHP et JS
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2013
    Messages : 1 876
    Par défaut
    Il faut transtyper le résultat de GetClass() qui retourne un TPersistentClass.

    https://docwiki.embarcadero.com/Libr...asses.GetClass

  8. #8
    Membre éclairé
    Avatar de Higgins
    Inscrit en
    Juillet 2002
    Messages
    539
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 539
    Par défaut
    Citation Envoyé par pprem Voir le message
    Il faut transtyper le résultat de GetClass() qui retourne un TPersistentClass.
    Oui, c'est comme ça que je procède pour mes classes "standards" mais dans ce cas précis, si je transtype j'ai une violation d'accès lors de l'appel à create avant même d'arriver à mon point d'arrêt dans le constructeur
    que ce soit avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    unObjet=ClasseGenerique<TMaClasse>(getclass('TMaClasse1')).create;
    ou avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    unObjet=GenMaClasse1(getclass('TMaClasse1')).create;
    J'avais remarqué que sans le transtypage explicite, je n'avais pas d'erreur. Le type affiché dans unObjet.classname étant correct, j'espérais qu'il y avait eu un transtypage implicite..

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Utilisation d'une classe générique
    Par bandit_debutant dans le forum Langage
    Réponses: 4
    Dernier message: 06/12/2006, 16h54
  2. Réponses: 3
    Dernier message: 05/10/2006, 17h15
  3. [C# 2.0] Un exemple de classe générique qui ne compile pas.
    Par Pierre8r dans le forum Windows Forms
    Réponses: 4
    Dernier message: 31/05/2006, 11h11
  4. [C#][ADO] Classe Générique ADO
    Par tscoops dans le forum Accès aux données
    Réponses: 2
    Dernier message: 15/11/2005, 14h21
  5. [Generics] Classe générique
    Par norkius dans le forum Langage
    Réponses: 4
    Dernier message: 29/10/2004, 15h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo