Почему Delphi не может определить тип для параметра TEnumerable <T>? - PullRequest
5 голосов
/ 26 апреля 2010

Рассмотрим следующее объявление универсального служебного класса в Delphi 2010:

TEnumerableUtils = class
public
  class function InferenceTest<T>(Param: T): T;
  class function Count<T>(Enumerable: TEnumerable<T>): Integer; overload;
  class function Count<T>(Enumerable: TEnumerable<T>; Filter: TPredicate<T>): Integer; overload;
end;

Каким-то образом здесь может возникнуть проблема с выводом типа компилятора:

var
  I: Integer;
  L: TList<Integer>;
begin
  TEnumerableUtils.InferenceTest(I);  // no problem here
  TEnumerableUtils.Count(L);          // does not compile: E2250 There is no overloaded version of 'Count' that can be called with these arguments
  TEnumerableUtils.Count<Integer>(L); // compiles fine
end;

Первый вызов работает как положено, и T правильно выводится как Integer.

Второй вызов не работает, если только я не добавлю <Integer> - тогда он работает, как видно из третьего вызова. Я делаю что-то не так или вывод типа в Delphi просто не поддерживает это (я не думаю, что это проблема в Java, поэтому ожидал, что она будет работать и в Delphi).

1 Ответ

9 голосов
/ 26 апреля 2010

Компилятору потребуется выполнить сопоставление с шаблоном для определения типов параметров; в настоящее время это не так. Компилятор ограничен довольно простым выводом - если тип параметра имеет тип параметра типа, то компилятор может понять это, но не намного дальше этого.

Тип аргумента в вашем примере - это не простой параметр типа, а скорее составной универсальный тип (он создается с помощью параметра типа метода T, но тем не менее он создается). Компилятор должен сделать два вывода, чтобы узнать значение T. Во-первых, он должен увидеть, что универсальный тип составного типа является предком универсального типа TList<T>; и ему также необходимо сопоставить параметр типа T в списке параметров типа составного типа с конкретным типом Integer в предке TList<T>.

...