Как передать несколько разных записей (не класс из-за ограничений delphi) в функцию? - PullRequest
1 голос
/ 13 марта 2010

У меня есть ряд записей, которые я не могу преобразовать в классы из-за ограничений Delphi (все они используют операторы классов для реализации сравнений).Но мне нужно пройти, чтобы сохранить их в классе, не зная, какой тип записи я использую.

Примерно так:

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

Теперь Delphi не принимает typecast из записи вTObject, и я не могу сделать их классами из-за ограничения Delphi.

Любой знает способ передачи различных записей в функцию и распознавания их типа при необходимости, как мы делаем с классом:

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

???

Ответы [ 4 ]

4 голосов
/ 14 марта 2010

Вы можете преобразовать их в классы, вам просто нужно обфусцировать оператор "Equal" с помощью виртуальной функции "IsEqual". Это значительно упростит вашу проблему и прояснит ваш код.

4 голосов
/ 14 марта 2010

Не думаю, что вы можете передавать разные записи в одну функцию, но вы можете сделать несколько перегруженных функций. Вот так:

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

Это решит вашу проблему?

2 голосов
/ 14 марта 2010

Записи не имеют информации о типах времени выполнения, что необходимо для определения их типов.

Помимо перегрузок, вы также можете передать тип, вы можете сделать это:

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

или вы могли бы сделать это, но голуби будут плакать:

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);
0 голосов
/ 14 марта 2010

Если вы используете Delphi 2010, вы, вероятно, могли бы передавать указатели на эти записи и использовать информацию о типе среды выполнения, чтобы определить, какой из них действительно был передан. Но это был бы очень уродливый код и, вероятно, довольно медленный.

Преобразование в классы и использование вызовов функций, а не перегрузок операторов, будет гораздо более читабельным.

...