2010-03-13 12 views
1

J'ai un certain nombre d'enregistrements que je ne peux pas convertir en classes en raison de la limitation Delphi (tous utilisent des opérateurs de classe pour implémenter des comparaisons). Mais je dois passer pour les stocker dans une classe ne sachant pas quel type d'enregistrement j'utilise.Comment passer plusieurs enregistrements différents (pas de classe en raison de limitations delphi) à une fonction?

Quelque chose comme ceci:

type R1 = record 
begin 
    x :Mytype; 
    class operator Equal(a,b:R1) 
end; 

type R2 = record 
begin 
    y :Mytype; 
    class operator Equal(a,b:R2) 
end; 

type Rn = record 
begin 
    z :Mytype; 
    class operator Equal(a,b:Rn) 
end; 

type TC = class 
begin 
    x : TObject; 
    y : Mytype; 
    function payload (n:TObject) 
end; 

function TC.payload(n:TObject) 
begin 
    x := n; 
end; 

program: 
    c : TC; 
    x : R1; 
    y : R2; 
    ... 
    c := TC.Create(): 
    n:=TOBject(x); 
    c.payload(n); 

Maintenant, Delphi n'acceptent pas typecast d'enregistrement à TObject, et je ne peux pas les rendre les classes Delphi en raison de la limitation.

Tout le monde sait un moyen de passer différents enregistrements à une fonction et reconnaître leur type en cas de besoin, comme nous le faisons avec la classe:

if x is TMyClass then TMyClass(x) ... 

???

+1

Quelle version de Delphi? Delphi 2010 prend en charge RTTI sur les enregistrements. –

Répondre

4

Je ne pense pas que vous pouvez passer différents enregistrements à une seule fonction , mais vous pouvez faire plusieurs surchargées fonctions. Comme ça:

type TC = class 
begin 
    x : TObject; 
    y : Mytype; 
    function payload (aRec : R1); overload; 
    function payload (aRec : R2); overload; 
end; 

Cela résoudra-t-il votre problème?

2

Les enregistrements ne contiennent pas d'informations sur le type d'exécution, ce qui est nécessaire pour détecter leurs types.

Outre les surcharges, vous pouvez également passer le type, vous pouvez le faire:

procedure Payload(aType : longint; data : Pointer); 
var 
    pr1 : ^R1; 
    pr2 : ^R2; 
    prN : ^RN; 
begin 
    case aType of 
    0 : pr1 := data; // might require a cast 
    1 : pr2 := data; 
    2 : prN := data; 
    end; 
end; 
Payload(0,@r1); 

ou vous pouvez le faire, mais les colombes pleurerez:

procedure Payload(aType : longint; var data); 
var 
    r1 : R1 absolute data; 
    r2 : R2 absolute data; 
    rN : RN absolute data; 
begin 
    // just be sure to check type before using the variable 
end; 
Payload(0,r1); 
4

Vous peut convertir ces Pour les classes, il suffit de désobstruer l'opérateur "Equal" avec une fonction virtuelle "IsEqual". Cela simplifiera votre problème et clarifiera énormément votre code.

0

Si vous utilisez Delphi 2010, vous pouvez probablement passer des pointeurs vers ces enregistrements et utiliser des informations de type à l'exécution pour détecter celle qui a réellement été transmise. Mais ce code serait très moche et probablement assez lent aussi.

La conversion en classes et l'utilisation d'appels de fonction plutôt que d'une surcharge de l'opérateur seraient beaucoup plus lisibles.