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 :

Classe generics et forward déclaration


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Points : 60
    Points
    60
    Par défaut Classe generics et forward déclaration
    Bonjour,

    J'utilise Delphi 2009 et les generics en abondance. Mais je rencontre un problème avec ce code :
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
     
    interface
     
    uses
      Generics.Collections, Classes;
     
    type
    TPersistentList<T : class, IPersistentObject<T>> = class(TObjectList<T>)
    private
      FAssociatedDAO : IDAO<T>;
    public
      constructor Create(AssociatedDAO : IDAO<T>);
      destructor Destroy; override;
      function GetById(Id : Integer) : T;
      procedure Update(ToUpdate : T);
      procedure Save;
    end;
     
    IPersistentObject<T : class> = interface (IInterface)
      function GetId : Integer;
      procedure SetId(Id : Integer);
    end;
     
    IDAO<T : class, IPersistentObject<T>> = interface(IInterface)
      function GetList() : TPersistentList<T>;
    end;
    donc comme vous pouvez le remarquer, il y a dépendance circulaire entre IDAO<T : class, IPersistentObject<T>> qui renvoi un TPersistentList<T> et TPersistentList<T : class, IPersistentObject<T>> qui garde un référence vers IDAO<T>

    Je suis donc obligé de déclarer des classes en forward déclaration en en-tête de la partie interface mais voila, je n'arrive pas à déclarer correctement avec les generics !!

    Si je déclare :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    type
     
    IPersistentObject<T> = interface;
    IDAO<T : class, IPersistentObject<T>> = interface;
    J'ai l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    [DCC Erreur] BaseDAO.pas(41): E2037 La déclaration de 'IDAO<T>' diffère de la déclaration précédente
    au niveau de la déclaration :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    IDAO<T : class, IPersistentObject<T>> = interface(IInterface)
      function GetList() : TPersistentList<T>;
    end;
    J'ai essayé de mettre en forward declaration : IDAO<T> = interface; IDAO<T : class> = interface;
    Toujours le même message d'erreur !

    Si quelqu'un à une idée ...

  2. #2
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    Salut,

    juste une question, peut être bête...

    pourquoi IPersistObject est générique sachant que y'a pas d'emploi du paramètre générique?

    J'aurais écris un truc comme ça a priori (je précise que je maitrise pas les génériques)

    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
    19
    20
    21
    22
    23
     
      IPersistentObject = interface [GUID]
        function GetId: Integer;
        procedure SetId(const Value: Integer);
        property Id: Integer read GetId write SetId;
      end;
     
      TPersistentList<T: class, IPersistentObject> = class;
     
      IDAO<T: class, IPersistentObject> = interface
        function GetList: TPersistentList<T>;
      end;
     
      TPersistentList<T: class, IPersistentObject> = class(TObjectList<T>)
      private
        FAssociatedDAO : IDAO<T>;
      public
        constructor Create(const AssociatedDAO : IDAO<T>);
        destructor Destroy; override;
        function GetById(Id: Integer): T;
        procedure Update(ToUpdate: T);
        procedure Save;
      end;
    Akim Merabet

  3. #3
    Membre du Club
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Points : 60
    Points
    60
    Par défaut
    En fait je n'ai pas mis tout le code pour alléger un peu mais IPersistentObject utilise la généricité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    IPersistentObject<T> = interface (IInterface)
      function GetId : Integer;
      procedure SetId(Id : Integer);
      function ToString : String;
      function Clone : T;
    end;
    Mais c'est vrais que sinon ta solution compile ... sauf que je perd ma fonctionnalité de Clonnage sur mes objets

  4. #4
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    peut être que ta fonction Clone peut renvoyer un IPersistentObject ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    IPersistentObject = interface (IInterface)
      function GetId : Integer;
      procedure SetId(Id : Integer);
      function ToString : String;
      function Clone : IPersistentObject;
    end;
    Mais bon, pour ton problème de départ, je sèche grave, désolé
    Akim Merabet

  5. #5
    Membre éclairé Avatar de Kaféine
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    569
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 569
    Points : 736
    Points
    736
    Par défaut
    Salut,

    encore un compromis...bizarre quand même la declaration avancé qui marche pas . syntaxe particulière ou bug?

    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
     
      IPersistentObject<T> = interface [GUID]
        function Clone: T;
      end;
     
      TPersistentList<T: class, IPersistentObject<T>> = class(TList<T>)
      private
        FAssociatedDAO: IInterface;
      public
        constructor Create(const AssociatedDAO: IInterface);
        function GetById(Id: Integer): T;
        procedure Update(ToUpdate: T);
        procedure Save;
      end;
     
      IDAO<T: class, IPersistentObject<T>> = interface [GUID]
        function GetList: TPersistentList<T>;
      end;
    "AssociatedDAO" en IInterface. puis interrogation pour choper un IDAO

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    var
      DAO: IDAO<T>;
      AList: TPersistentList<T>;
      AItem, AClone: T;
    begin
      if Supports(FAssociatedDAO, IDAO<T>, DAO) then
      begin
        AList := DAO.GetList;
        for AItem in AList do
        begin
          AClone := AItem.Clone;
        end;
      end;
    Akim Merabet

  6. #6
    Membre du Club
    Développeur informatique
    Inscrit en
    Juillet 2005
    Messages
    87
    Détails du profil
    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Juillet 2005
    Messages : 87
    Points : 60
    Points
    60
    Par défaut
    Merci,

    J'ai bien ta deuxième solution, même si ce n'est pas l'idéal c'est un bon compromis.

    Il y a quand même des choses étranges quand on pousse un peu loin les generics ...

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

Discussions similaires

  1. Figer une variable de classe lors de sa déclaration dans une itérative
    Par Freeluvs dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 16/02/2010, 15h16
  2. Class Generic et GetType
    Par topolino dans le forum ASP.NET
    Réponses: 2
    Dernier message: 27/02/2009, 15h00
  3. Cast d'une classe generic
    Par Seth77 dans le forum C#
    Réponses: 3
    Dernier message: 27/06/2008, 14h27
  4. Réponses: 1
    Dernier message: 05/04/2008, 16h13
  5. forward déclaration de strcuture
    Par BigNic dans le forum C++
    Réponses: 10
    Dernier message: 14/04/2006, 14h07

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