Simplification de propriétés

Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
-
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
-
Bonjour tout le monde,

Voici mon problème j'ai une class avec une 30aine de propriétés de types différents ( TColor, integer, ennumérés ) avec les mêmes traitements à faire sur chacune. Entre autre, une chose simple: savoir si la propriété à été modifiée ou pas. Et donc ça m'embète franchement de me tapper 30 accesseurs qui sont identiques aux types près alors que par exemple un DWord ça reste un DWord. J'ai donc pensé a mettre tous les types de même taille dans un tableau de record variables.
Et j'ai testé cette "solution" pour le Set:

    TAnyDWord=Record
      Case Integer Of
        0: ( Int: Integer;  );
        1: ( Ptr: Pointer;  );
        2: ( Clr: TColor;   );
    End;

  TTestClass = class(TObject)
  private
    FAssigned: DWord; // verrif quelles propriétés sont assignées.
    FTest: Array[0..2] Of TAnyDWORD;

    Procedure SetDWORD(Index: Integer; Const Value);
  public
    Property a: Integer Index 0 Read FTest[0].Int Write SetDWord;
    Property b: Pointer Index 1 Read FTest[1].Ptr Write SetDWord;
    Property c: TColor  Index 2 Read FTest[2].Clr Write SetDWord;
  end;

TTestClass.SetDWord(Index: Integer; Const Value);
Begin
  FAssigned:=FAssigned Or (1 shl Index);
  DWord(FTest[index]):=DWord(Value);
End;

Normalement comme le paramètre Value n'est pas typé ça devrait marcher... Pouvez vous me dire pourquoi ça ne marche pas ou au pire m'aider à trouver une solution ?

Petite précision tout de même, je tiens a garder les types différents aux propriétés.
Désolé de ne pas être très clair. Merci d'avance a ceux qui répondront ^^

bouh

5 réponses

Messages postés
215
Date d'inscription
mardi 29 juillet 2003
Statut
Membre
Dernière intervention
1 septembre 2006

Salut,

Petit extrait de l'aide de Delphi:

Les spécificateurs d'indice permettent à plusieurs propriétés de partager les mêmes méthodes d'accès tout en représentant des valeurs différentes. Un spécificateur d'indice est constitué de la directive index suivie d'une constante entière comprise entre –2147483647 et 2147483647. Si une propriété a un spécificateur d'indice, ses spécificateurs read et write doivent indiquer des méthodes et pas des champs. Par exemple :


type


  TRectangle = class
  private
    FCoordonnees: array[0..3] of Longint;
    function LitCoordonnees(Indice: Integer): Longint;
    procedure EcritCoordonnees(Indice: Integer; Valeur: Longint);
  public
    property Gauche: Longint index 0 read LitCoordonnees write EcritCoordonnees;
    property Haut: Longint index 1 read LitCoordonnees write EcritCoordonnees;
    property Droite: Longint index 2 read LitCoordonnees write EcritCoordonnees;
    property Bas: Longint index 3 read LitCoordonnees write EcritCoordonnees;


    property Coordonnees [Indice: Integer]: Longint read LitCoordonnees write EcritCoordonnees;
    ...
  end;


La méthode d'accès d'une propriété ayant un spécificateur d'accès doit prendre un paramètre supplémentaire de type Integer. Pour une fonction read, ce doit être le dernier paramètre ; pour une procédure write, ce doit être l'avant-dernier paramètre (avant le paramètre spécifiant la valeur de la propriété). Quand un programme accède à la propriété, la constante entière est automatiquement transmise à la méthode d'accès.
Etant donné les déclarations précédentes, si Rectangle est de type TRectangle, alors :


Rectangle.Droite := Rectangle.Gauche + 100;


correspond à :


Rectangle.EcritCoordonnees(2, Rectangle.LitCoordonnees(0) + 100);

Ceci devrait éclairer ta lanterne !

j!nH
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
1
Je suis désolé, mais j'ai bien précisé que les types des propriétés étaient différents et que je souhaitais garder cette différence, sinon biensûr ce serait extrèmement simple. Merci quand même mais tu m'aide pas.

bouh
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
38
tu peu utiliser les variants mais c'est un peu lourd.
on pourrait egalement utiliser TVarData et VarAsType (lourd a gerer) .. 

type
  TVarTypes = (vtInteger=$0003, vtFloat=$0004);

  TMyClass = class(TObject)
  private
    fInts : array[0..9] of Integer;
    fFlts : array[0..9] of single;
    function GetVariant(Index: integer; TIndex : TVarTypes) : variant;
    procedure SetVariant(Index: integer; TIndex : TVarTypes; Value : variant);
  protected
    procedure Change(const TIndex : TVarTypes; const Index : integer); virtual;
  public
    property Ints[index : integer] : variant index vtInteger read GetVariant write SetVariant;
    property Flts[index : integer] : variant index vtFloat read GetVariant write SetVariant;
  end;

function TMyClass.GetVariant(Index: integer; TIndex : TVarTypes) : variant;
begin
  case TIndex of
    vtInteger : result := VarAsType(fInts[Index],varInteger);
    vtFloat   : result := VarAsType(fFlts[Index],varSingle);
  end;
end;

procedure TMyClass.SetVariant(Index : integer; TIndex : TVarTypes; Value : variant);
begin
  case TIndex of
    vtInteger : if fInts[Index] <> integer(Value) then begin
                   fInts[Index] := integer(Value);
                   change(TIndex,Index);
                end;
    vtFloat   : if fFlts[Index] <> single(Value) then begin
                   fFlts[Index] := single(Value);
                   change(TIndex,Index);
                end;
  end;
end;

procedure TMyClass.Change(const TIndex : TVarTypes; const Index : integer);
begin
  // change method //
end;
  

<hr size="2" width="100%" />Croc (click me)
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006
1
Désolé de répondre un peu tard ( en fait j'attendais plus de réponse ^^' )
En fait je souhaite garder les types car c'est pour un composant non visuel. Je voudrais éviter au programmeur qui utilisera ce composant de passer 2heures à chercher quelles valeurs vont bien dans quelles propriétés. C'est pour ça que je veux absolument garder les types bien définis. Et pour ça aussi que je n'utilise pas de constantes integer ou de variants par exemple.

Enfin bref tout ça pour dire que je pense m'être méchament planté à la base, je vais repenser le tout parceque de cette façon c'est ingérable. Merci quand même de ta réponse :)

bouh
Messages postés
4297
Date d'inscription
samedi 19 janvier 2002
Statut
Modérateur
Dernière intervention
9 janvier 2013
31