NOTA: La seguente risposta è errata, che inizia come da una premessa imperfetta! Piuttosto che redarre l'intera cosa per salvare i miei rossori, l'ho lasciato intatto in modo che i commenti che evidenziano l'errore abbiano senso,
Come può essere supportato questo in modo sicuro?
Given (se questo è quello che hai in mente, che penso che sia):
type
TFoo<T> = class end;
PFoo<T> = ^TFoo<T>;
Poi, se si ha:
var
a, b: TFoo<T>;
p: PFoo<T>;
a := TFoo<String>.Create;
b := TFoo<Integer>.Create;
Poi entrambe le seguenti sarebbe ammissibile:
p := @a;
p := @b;
In qualsiasi momento p potrebbe risolvere il riferimento a qualsiasi TFoo di T, ma in qualsiasi momento può sempre fare riferimento solo a uno specifico T. Non riesco a vedere alcun meccanismo di compilazione compatibile con i tipi per garantire che le code dereferences p correttamente.
Un modo per aggirare questo problema (non una limitazione del compilatore, ma una limitazione di cercare di esprimere qualcosa in modo sicuro tipo per il quale la sicurezza di tipo semplicemente non può essere espresso) sarebbe quello di creare derivati specifici del tipo di questi tipi e li usano. Al punto in cui si vuole dereferenziare si è quasi certamente andando a conoscere il tipo T comunque:
type
TFoo<T> = class end;
TFooString = TFoo<String>;
PFooString = ^TFooString;
var
p: PFooString;
a := TFoo<Integer>;
b := TFoo<String>;
p := @a; // Should not compile
p := @b; // This is OK
Questo è possibile anche in Delphi 2010.
Tuttavia, preoccupante, a indagare questo ho scoprire che:
p := @a; // Should not compile
in effetti compilazione. Il che mi sembra sbagliato. Molto sbagliato. E potrebbe indicare (ancora) un altro difetto nell'implementazione dei generici in Delfi.
Ecco i draghi ...
Draghi in questo caso ;-). –
+1 Scrive molto bene. Hai fatto QC a trovare ciò che non dovrebbe essere compilato? –
@ Marjan: no. Prima di tutto, non ho accesso a XE per confermare che il bug esista ancora - se è già stato risolto in XE allora non c'è motivo di segnalarlo contro il 2010 poiché non ci saranno ulteriori correzioni per il 2010 rilasciate. In secondo luogo, potrebbe essere una conseguenza del fatto che la classe generica TFoo in realtà non fa riferimento al tipo T. Se lo facesse, il compilatore potrebbe essere più severo - non ho ancora testato questa ipotesi (per esempio, dovrebbe non riuscire a compilare in ogni caso). Ma da qui la mia osservazione che "potrebbe" indicare un difetto, non che lo faccia assolutamente. :) – Deltics