Вариант записи вместо перегруженного типа объекта?

Я работаю над проблемой, в которой мне нужно динамически изменять размер массива, для чего требуются многочисленные операции. Я успешно закодировал два класса, t_one и t_two:

tarray1 : array of longint;
tarray2 : array of single;
t_one = class(tobject)
  Public
  Myarray1 : tarray1;
  constructor create;
  destructor destroy;
  procedure oneofmany; 
end;
t_two = class(tobject)
  Public
  Myarray1 : tarray2;
  constructor create;
  destructor destroy;
  procedure oneofmany; 
end;

Два объекта имеют почти идентичный код, за исключением того, что Myarray1 - это массив single в одном случае и массив longint в другом. Единственный способ превратить это в единый объект, чтобы использовать различные массивы (что замедлит работу)? Вариантная запись неэффективна и для того, что я делаю. Если бы я мог сказать

case mysituation of
  integerdata : (myarray1 : tarray1);
  realdata: (myarray1 : tarray2);
end;

это было бы то, что я имел в виду, но очевидно, что этот синтаксис - анафема. Конечно, есть места, где вызовы методов и результаты функций должны знать тип данных, но после определения они согласованы. Мысли? Использовать вариантный массив и терпеть замедление?

2 ответа

Решение

Один из возможных подходов - сделать единственный класс, используя дженерики

  TA<T> = class
  public
     Arr : TArray<T>;
     destructor destroy;override;
  end;
...
procedure TForm1.Button1Click(Sender: TObject);
var
  A: TA<Integer>;
  B: TA<Single>;
begin
  A := TA<Integer>.Create;
  B := TA<Single>.Create;
  A.Arr := [1,2,3];
  B.Arr := [Pi, Ln(2)];
  Memo1.Lines.Add(A.Arr[0].ToString);
  Memo1.Lines.Add(B.Arr[0].ToString);
end;

Оказывается, ответ приводит к довольно запутанным решениям. Есть причина для строгой типизации! Поскольку невозможно иметь несколько типов возвращаемых функций с одним и тем же именем, можно увязнуть в функциях с одинаковыми именами для разных типов аргументов. Если вы пытаетесь

var
  mypointer : pointer;
begin
  case argtype of
    integer: mypointer := @A;
    single : mypointer := @B;
end;

тогда вам все равно нужно вводить mypointer каждый раз, когда вы его используете. Оказывается, это не очень помогает.

Другие вопросы по тегам