Delphi - оператор неявного приведения типов не работает для параметров метода

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

type
  TArrayWrapper = record
    class operator Implicit(AArray: array of TObject): TArrayWrapper; overload;
    Items: TArray<TObject>;

    procedure Add(AItem: TObject);
    ...
  end;

Итак, я могу делать такие вещи, как:

procedure DoSomething;
var
  myArray: TArrayWrapper;
begin
  myArray := [Obj1, Obj2, Obj3];
  ...
end;

Проблема возникает, когда я пытаюсь передать массив Integer методу, который имеет в качестве параметра TArrayWrapper:

procedure DoSomethingElse(AArrayWrapper: TArrayWrapper);
begin
    ...
end;


procedure DoSomething;
var
  myArray: TArrayWrapper;
begin
  myArray := [Obj1, Obj2, Obj3];
  DoSomethingElse(myArray);   <--- Works!!!!

  DoSomethingElse([Obj1, Obj2, Obj3]); <--- Error E2001: Ordinal type required -> It is considering it like a set, not as an array
end;

Что может происходить?

Заранее спасибо.

Это недостаток компилятора

Stefan Glienke 30.05.2019 13:47
Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
4
1
344
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Компилятор не реализовал строковые операции над динамическим массивом для операторов класса, когда в качестве параметра используется запись/класс.

Насколько я вижу, для этого нет отчета QP.Теперь есть, см. ниже.

Подобный пример можно найти в комментариях здесь: Динамические массивы в Delphi XE7


Обходной путь:

DoSomethingElse(TArray<TObject>.Create(Obj1, Obj2, Obj3));

Или, как предлагает @Stefan, чтобы избежать ненужных выделений. Добавьте в запись конструктор:

type
  TArrayWrapper = record
    class operator Implicit(AArray: array of TObject): TArrayWrapper; 
    constructor Init( const AArray: array of TObject);
  end;

DoSomethingElse(TArrayWrapper.Init([obj1,obj2,obj3]));

Сообщается как: Операторы класса RSP-24610 не принимают динамические массивы, передаваемые со скобками

В качестве обходного пути я бы предпочел добавить ctor для типа TArrayWrapper с параметром array of TObject, чем выполнять немедленное динамическое выделение массива и неявный вызов оператора плюс добавленный компилятор CopyRecord

Stefan Glienke 30.05.2019 13:53

@StefanGlienke, спасибо. Добавил ваше предложение в ответ. Я сообщу об этом QP позже сегодня.

LU RD 30.05.2019 14:04

Я уже использовал это решение. Код менее элегантен, чем просто передача массива, но он работает. Спасибо большое.

Leon 30.05.2019 14:22

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