2014-12-03 2 views
5

Скажем, у меня есть класс с двумя общими методами:Общих методы типа вывод

TMyClass = class 
    procedure DoWith<T: class> (obj: T); 
    procedure DoFor<T: class> (proc: TProc<T>); 
end; 

Теперь, когда я хочу вызвать любого из этих двух методов с определенным параметром типа, Delphi может определить тип для DoWith метод, так что я могу назвать это либо

MyClass.DoWith <TButton> (MyButton) 

или

MyClass.DoWith (MyButton) 

Компилятор Delphi будет с удовольствием скомпилировать оба. Но если опустить параметр типа в методе DoFor, компилятор Delphi жалуется на параметре отсутствующего типа:

MyClass.DoFor<TButton>(procedure (Button: TButton) begin .... end); // compiles 


MyClass.DoFor(procedure (Button: TButton) begin .... end); // doesn't compile 

Теперь мой вопрос: Является ли это просто недостаток компилятора, или есть какая-либо логическая причина (что я еще не понял), который запрещает компилятору правильно вывести тип для метода DoFor?

+0

Это выглядит как ограничение компилятора. В Delphi общий вывод типа очень слабый. –

ответ

5

Причина, по которой не может сделать вывод T из TProc<T> аргумента является то, что в то время TProc<TButton> является тип построен без какой-либо информации, которую он первоначально был TProc<T>.

Чтобы сделать это, вы должны указать тип из анонимной сигнатуры метода, который не работает (я думаю, что Барри Келли мог бы объяснить это лучше, и я думаю, что он когда-то писал о трудностях лямбда и вывода типа в Delphi).

Единственный тип вывода, который использует компилятор Delphi, является аргументом типа T. Даже с несколькими аргументами, которые не работают часто и даже меньше, если у вас более одного типа типового типа.

Edit: я нашел комментарий, где Барри объяснена немного о трудностях вывода типа и лямбды в компиляторе Delphi: http://www.deltics.co.nz/blog/posts/244/comment-page-1#comment-107

+0

Спасибо Stefan: Ваш ответ дал мне недостающие бит, чтобы понять, что есть логическая причина для этого поведения компилятора. – iamjoosy

+1

@iamjoosy Я лично считаю это нелогичным. Я бы предпочел, чтобы компилятор гораздо лучше выводил типы. Я не вижу причин, почему он не мог этого сделать. Множество других языков намного лучше, чем Delphi. –

+0

@DavidHeffernan Сначала я не видел никакой логики в компиляторе bahaviour сам, следовательно, мой вопрос здесь. Но ответ Стефана открыл мои глаза, объяснив, как компилятор рассматривает выражение: он строит фактические типы изнутри наружу, тем самым сначала создавая анонимную функцию с типом TButton, а затем работает с этим типом в окружающей процедуре, и в этот момент компилятор «забыл», что анонимная функция была построена из того же параметра типа T, который украшает окружающую функцию. – iamjoosy

Смежные вопросы