2014-12-03 20 views
5

Diciamo che ho una classe con due metodi generici:metodi generici tipo di inferenza

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

Ora, quando voglio chiamare uno di questi due metodi con un parametro di tipo specifico, Delphi può dedurre il tipo per la DoWith metodo, così posso chiamarla sia con

MyClass.DoWith <TButton> (MyButton) 

o

MyClass.DoWith (MyButton) 

Il compilatore Delphi compilerà felicemente entrambi. Ma se tralascio il parametro di tipo nel metodo DoFor, il compilatore Delphi lamenta il parametro di tipo mancante:

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


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

Ora la mia domanda è: E 'solo una lacuna del compilatore, o c'è alcuna ragione logica (che non ho ancora capito) che impedisce al compilatore di inferire correttamente il tipo per il metodo DoFor?

+0

Sembra una limitazione del compilatore. L'inferenza di tipo generico è molto debole in Delphi. –

risposta

5

Il motivo per cui non può dedurre T da un argomento TProc<T> è che in quel momento TProc<TButton> è un tipo costruito senza alcuna informazione che in origine era un TProc<T>.

Per fare ciò dovrebbe dedurre il tipo dalla firma del metodo anonimo che non funziona (suppongo che Barry Kelly possa spiegarlo meglio e penso che una volta abbia scritto sulle difficoltà di lambda e l'inferenza di tipo in Delphi).

L'unica inferenza di tipo del compilatore Delphi è un argomento di tipo T. Anche con più argomenti che non funzionano spesso e ancor meno se si dispone di più di un parametro di tipo generico.

Edit: ho trovato un commento in cui Barry ha spiegato un po 'circa le difficoltà di inferenza e lambda nel compilatore Delphi: http://www.deltics.co.nz/blog/posts/244/comment-page-1#comment-107

+0

Grazie Stefan: La tua risposta mi ha dato i bit mancanti per capire che c'è un motivo logico per questo comportamento del compilatore. – iamjoosy

+1

@iamjoosy Personalmente trovo questo illogico. Preferirei che il compilatore potesse inferire i tipi molto meglio. Non vedo alcuna ragione per cui non possa farlo. Un sacco di altre lingue gestiscono questo molto meglio di Delphi. –

+0

@DavidHeffernan All'inizio non riuscivo a vedere alcuna logica nel compilatore bahaviour me stesso, quindi la mia domanda qui. Ma la risposta di Stefan mi ha aperto gli occhi spiegando come il compilatore tratta l'espressione: costruisce i tipi effettivi dall'interno all'esterno, quindi prima costruisce la funzione anonima con il tipo di TButton e poi funziona con questo tipo nella procedura circostante e a questo punto il il compilatore ha "dimenticato" che la funzione anonima è stata costruita dallo stesso parametro di tipo T che decora la funzione circostante. – iamjoosy