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 :

[D12 +] utilisation du type record


Sujet :

Langage Delphi

  1. #1
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 890
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 890
    Billets dans le blog
    66
    Par défaut [D12 +] utilisation du type record
    Bonjour,

    Jusque là je n'avais jamais vraiment utilisé de Record voici celui que j'ai créé (vous m'excuserez pour les noms de propriété ce n'est qu'un essai
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    unit dialoguetypes;
     
    interface
    type  specialdirs = Record
      private
        Fname: String;
        Ficonnumber: integer;
        Ffullname: String;
        procedure Setfullname(const Value: String);
        procedure Seticonnumber(const Value: integer);
        procedure Setname(const Value: String);
      public
       property name : String read Fname write Setname;
       property fullname : String read Ffullname write Setfullname;
       property iconnumber : integer read Ficonnumber write Seticonnumber;
       constructor Create(aname,apath : string; aicon : integer=1);
      end;
    implementation
     
    { specialdirs }
     
    constructor specialdirs.Create(aname, apath: string; aicon: integer=1);
    begin
    name:=aname;
    fullname:=apath;
    iconnumber:=aicon;
    end;
     
    procedure specialdirs.Setfullname(const Value: String);
    begin
      Ffullname := Value;
    end;
     
    procedure specialdirs.Seticonnumber(const Value: integer);
    begin
      Ficonnumber := Value;
    end;
     
    procedure specialdirs.Setname(const Value: String);
    begin
      Fname := Value;
    end;
     
    end.
    voilà comme je voudrais l'utiliser, sauf que j'ai un problème (sinon je n'aurais pas fait de post)
    Nom : Capture.png
Affichages : 202
Taille : 17,8 Ko


    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
    28
      TForm1 = class(TForm)
    ..
    private
       ... 
       property pinneddirs : TList<specialdirs> read Fpinneddirs write Setpinneddirs;
    ..
    
    procedure TForm1.Setpinneddirs(const Value: TList<specialdirs>);
    var anItem : TTreeviewItem;
        d : specialdirs;
    begin
      Fpinneddirs := Value;
      for var i:=0 to Fpinneddirs.count-1 do
        begin
          d:=Fpinneddirs[i];
          anitem:= TTreeviewItem.Create(self);
          anItem.Parent:=TreeView1;
          anItem.Text:=d.name;   // PLANTON voir image, les valeurs ne sont pas bonnes
          anItem.Index:=i;
        end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    var d : specialdirs;
    begin
    PinnedDirs:=TList<Specialdirs>.Create([d.Create('test','c:\test',1),d.Create('2test','C:\test2')]);
    end;
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes), D13 (Florence)
    SGBD : Firebird 2.5, 3, 5 et SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 231
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 231
    Par défaut
    Cela me rappelle ce sujet Copie de variable de type record comprenant des éléments de type structuré

    J'en suis encore au constructor static pour les record, c'est depuis quand les self constructor ?
    EDIT : Eh bien en D10 ça existe, faudra que j'essaye pour voir la différence même si ça ne semble pas très utile en dehors du constructeur de copie.

    cela me choque le d.create() ça ressemble plus à constructeur de copie ou une fonction Init qu'à un vrai constructeur
    J'ai même peur que cela appelle le destructeur de d sur la fin de bloc

    Ceci est-il possible avec le self constructor ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    PinnedDirs:=TList<Specialdirs>.Create([specialdirs.Create('test','c:\test',1),specialdirs.Create('2test','C:\test2')]);


    C'est peut-être le cas du constructor static qui a ma préférence, j'ai vérifié, je n'utilise que ça !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    class function Create(const aname, apath: string; aicon: integer=1): specialdirs; static; inline;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class constructor specialdirs.Create(const aname, apath: string; aicon: integer=1)): specialdirs;
    begin
      Result.name:=aname;
      Result.fullname:=apath;
      Result.iconnumber:=aicon;
    end;

    As-tu pensé à ajouter un class operator Assign pour recopier proprement le contenu du record des membres privés car est-ce que la copie de record copie uniquement la partie "publique" (celle que l'on avait dans le record classique sans visibilité)

    Théorique purement, j'ai un D10 ça n'existe pas (j'ai même pas vérifié)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class operator specialdirs.Assign (var Dest: specialdirs; const [ref] Src: specialdirs);
    begin
      Dest.Fname := Src.Fname;
      Dest.Ficonnumber := Src.Ficonnumber;
      Dest.Ffullname:= Src.Ffullname;
    end;
    Aide via F1 - Utilisez l'I.A. - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité ! Sachez-le : l'IA remplace la très grande majorité des développeurs, pas seulement les ignares ...

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 890
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 890
    Billets dans le blog
    66
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    cela me choque le d.create()
    Oui et avec raison ! quand on a le nez dans le guidon on ne fait pas attention à ce genre de choses

    le bon code d'utilisation
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    pinneddirs:=Tlist<Specialdirs>.Create([Specialdirs.Create('test','c:\test',1),Specialdirs.Create('2test','C:\test2')]);
    end;
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes), D13 (Florence)
    SGBD : Firebird 2.5, 3, 5 et SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  4. #4
    Invité de passage
    Homme Profil pro
         ​​​  
    Inscrit en
    Décembre 2025
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité :      ​​​  

    Informations forums :
    Inscription : Décembre 2025
    Messages : 39
    Par défaut
    La question pourquoi utiliser une structure alors qu'une classe est plus pratique et surtout ça évite les copies parasites inutiles comme dans votre code.

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 890
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 890
    Billets dans le blog
    66
    Par défaut
    Bonne question. D'habitude, j'utilise des classes.
    C'est, justement, pour tenter de comprendre la différence que j'ai utilisé un type record, surtout que ce type a évolué lors de la sortie de la version 12 (à moins que ce soit 11.x, je vais vérifier).

    Pour moi la différence essentielle est qu'un record n'est pas un objet mais c'est sujet à débat.

    Lecture : https://docwiki.embarcadero.com/RADS...3%A9s_(Delphi) chapitre Enregistrements (avancés)
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes), D13 (Florence)
    SGBD : Firebird 2.5, 3, 5 et SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  6. #6
    Invité de passage
    Homme Profil pro
         ​​​  
    Inscrit en
    Décembre 2025
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité :      ​​​  

    Informations forums :
    Inscription : Décembre 2025
    Messages : 39
    Par défaut
    Bonjour,
    Les structure sont incontournables pour créer les type qui sont par nature transmis par valeur les entiers les floats Dates ou d'en ajouter de nouveaux types, avec les structures modernes il est possible surcharger les opérateurs ou les rendre compatible avec n'importe quel type ou extraire les données binaires et l'afficher d'une autre manière ex champs de bits non supportés dans les anciennes versions.. toutefois il faut rester prudent car les structures sont passés par valeur et cela devient un gros problème avec les grosses structure .. les copies parasites peuvent apparaître à n'importe quel endroit.

    utiliser une structure dans le résultat d'une fonction peut mener à une grosse confusion car losque on fait :
    fonc().name : = 'new name' ;
    on imagine modifier la structure mais la on modifie la copie .

    aussi les structures dans les property sont difficiles à gérer car elle demande qu'une structure complète soit assignée sans parler de la copie parasite
    s : = Liste[i].name ; // une copie parasite

    Liste[i].name : ='texte' ; // opération impossible

  7. #7
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    6 008
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 6 008
    Par défaut
    Citation Envoyé par Informt2025 Voir le message
    utiliser une structure dans le résultat d'une fonction peut mener à une grosse confusion car losque on fait :
    fonc().name : = 'new name' ;
    on imagine modifier la structure mais la on modifie la copie .
    Ca ne compilera pas avec l'erreur "E2064 La partie gauche n'est pas affectable".

  8. #8
    Invité de passage
    Homme Profil pro
         ​​​  
    Inscrit en
    Décembre 2025
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité :      ​​​  

    Informations forums :
    Inscription : Décembre 2025
    Messages : 39
    Par défaut
    En principe le Result d'une fonction est RValue en lecture seule et les tentatives de modification seront rejetées à la compilation

  9. #9
    Membre éclairé

    Homme Profil pro
    Mathématicien
    Inscrit en
    Juin 2016
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Mathématicien

    Informations forums :
    Inscription : Juin 2016
    Messages : 38
    Par défaut
    Pour compléter la question record/classe, je ne vois pas le record comme un simple substitut plus léger à une classe.

    - Je l’utilise plutôt quand je veux manipuler une valeur ou un petit état autonome. Par exemple, dans un traitement asynchrone avec callback, il peut être pratique de préparer un record contenant uniquement les informations nécessaires au traitement, plutôt que de dépendre directement d’une instance de classe qui pourra être modifiée ou libérée avant l’exécution du callback.

    Évidemment, ça reste à utiliser en gardant en tête la sémantique valeur du record : copie à l’affectation, passage par valeur, comportement parfois moins naturel avec les propriétés ou les listes.

    - Un autre cas où je trouve les records pratiques, c’est autour des types énumérés, via un record helper. Ça permet de garder près du type les conversions, les libellés, les mappings ou les petits traitements associés :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    type
      T_Enum = (
        item_1,
        item_2,
        item_n
      );
     
      T_EnumHelper = record helper for T_Enum
        class function Parse(const Value: string; out Enum: T_Enum): Boolean; static; inline;
        function ToString: string;
      end;
    - Un record peut aussi servir simplement à regrouper des méthodes statiques quand il n’y a pas vraiment d’objet à instancier :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    type
      TMonTypeTools = record
        class function MaFonction(const P: TMonType): TMonType; static;
      end;
    Donc pour moi, le record n’est pas “mieux” qu’une classe. C’est juste un outil différent, utile quand on veut raisonner en valeur ou rapprocher quelques fonctions d’un type simple. Dès qu’il y a identité, cycle de vie, héritage, interface ou polymorphisme, la classe reste naturellement plus adaptée.

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 890
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 890
    Billets dans le blog
    66
    Par défaut
    @MaxiDonkey Je crois que tu exposes là, la meilleure réponse à mon questionnement Class vs Record
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes), D13 (Florence)
    SGBD : Firebird 2.5, 3, 5 et SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  11. #11
    Invité de passage
    Homme Profil pro
         ​​​  
    Inscrit en
    Décembre 2025
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité :      ​​​  

    Informations forums :
    Inscription : Décembre 2025
    Messages : 39
    Par défaut
    - Un record peut aussi servir simplement à regrouper des méthodes statiques quand il n’y a pas vraiment d’objet à instancier
    En fait, parmi les trucs ayant bradé Delphi -le langage- c'est l'utilisation des records et classes comme namespace qui n'est pas supporté nativement sans tenir compte de la particularité du Delphi qui reserve l'initial T pour les types donc ce qui marche dans les autres langages ne l'est pas forcément en Delphi et surtout sans adaptation adéquate on aurait aimé un mécanisme pour distinguer entre l'ecpace de type et celui du namespace.

  12. #12
    Membre éclairé

    Homme Profil pro
    Mathématicien
    Inscrit en
    Juin 2016
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Marne (Champagne Ardenne)

    Informations professionnelles :
    Activité : Mathématicien

    Informations forums :
    Inscription : Juin 2016
    Messages : 38
    Par défaut
    Oui, je suis d’accord : ce n’est pas un namespace Delphi au sens propre.
    Je voyais plutôt ça comme un confort de lisibilité permettant de regrouper des responsabilités liées entre elles, sans instancier une classe lorsqu’il n’y a pas réellement d’objet à manipuler.
    Pour un découpage plus large ou purement organisationnel, une unité dédiée reste évidemment plus naturelle en Delphi.

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

Discussions similaires

  1. [PLSQL] TYPE RECORD
    Par romuald9999 dans le forum Oracle
    Réponses: 13
    Dernier message: 19/08/2004, 15h18
  2. [LG]fichier typé; record et pointeurs
    Par rigel dans le forum Langage
    Réponses: 6
    Dernier message: 12/05/2004, 16h12
  3. [LG]Resultat de fonction de type Record ?
    Par Mike888 dans le forum Langage
    Réponses: 10
    Dernier message: 24/01/2004, 22h48
  4. utilisation du type DATE d'interbase
    Par dibak dans le forum InterBase
    Réponses: 4
    Dernier message: 05/01/2004, 15h03
  5. Structure de données de type "RECORD"
    Par chaours dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 30/09/2002, 17h10

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