views:

227

answers:

4

Hi to all. I have a number of records I cannot convert to classes due to Delphi limitation (all of them uses class operators to implement comparisons). But I have to pass to store them in a class not knowing which record type I'm using.

Something like this:

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);

Now, Delphi do not accept typecast from record to TObject, and I cannot make them classes due to Delphi limitation.

Anyone knows a way to pass different records to a function and recognize their type when needed, as we do with class:

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

???

+4  A: 

I don't think you can pass different records to a single function, but you can make several overloaded functions. Like so:

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

Will that solve your problem?

Svein Bringsli
+2  A: 

Records don't have Run Time Type Information, which is what you'd need to detect their types.

Besides overloads, you can also pass the type, you can do this:

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);

or you could do this, but doves will cry:

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);
Zartog
+4  A: 

You can convert these to classes, you simply have to de-obfuscate the "Equal" operator with a virtual "IsEqual" function. It will simplify your problem and clarify your code enormously.

Deltics
A: 

If you are using Delphi 2010, you could probably pass around pointers to these records and use runtime type information to detect which one was actually passed. But this would be very ugly code and probably quite slow as well.

Converting to classes and using function calls rather than operator overloading would be much more readable.

dummzeuch