NOTA: La siguiente respuesta es errónea, comenzando como lo hace desde una premisa defectuosa. En lugar de redactar todo para guardar mis rubores, lo dejé intacto para que los comentarios que resaltan el error tengan sentido,
¿Cómo se puede admitir esto de forma segura?
Dada (si esto es lo que tienes en mente, que creo que es):
type
TFoo<T> = class end;
PFoo<T> = ^TFoo<T>;
Entonces, si tenemos:
var
a, b: TFoo<T>;
p: PFoo<T>;
a := TFoo<String>.Create;
b := TFoo<Integer>.Create;
A continuación, ambos de los siguientes sería permisible:
p := @a;
p := @b;
en un momento dado p poder eliminar la referencia a cualquier TFoo de T, pero en un momento dado solo puede hacer referencia a un específico. No puedo ver ningún mecanismo de tiempo de compilación seguro para que las desreferencias de código p correctamente.
Una forma de evitar este problema (no una limitación del compilador, sino una limitación de intentar expresar algo de una manera segura, para la cual la seguridad del tipo simplemente no se puede expresar) sería crear derivados de tipo específico de estos tipos y usarlos. En el punto en el que desea eliminar la referencia que está casi seguro que va a saber el tipo T todos modos:
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
Esto es posible incluso en Delphi 2010.
Sin embargo, preocupante, en la investigación de este I encuentra que:
p := @a; // Should not compile
DOES de hecho compilar. Lo cual me parece erróneo. Muy mal. Y podría señalar (aún) otro defecto en la implementación de genéricos en Delphi.
Aquí hay dragones ...
Dragons en este caso ;-). –
+1 Muy buena redacción. ¿Has hecho un QC de tu hallazgo de lo que se compila pero no se debe compilar? –
@Marjan: No. En primer lugar, no tengo acceso a XE para confirmar que la falla todavía existe; si ya se ha corregido en XE, no tiene sentido informarlo en contra de 2010, ya que no se lanzarán nuevas soluciones para 2010. En segundo lugar, puede ser una consecuencia del hecho de que la clase genérica TFoo no hace referencia realmente al tipo T. Si lo hizo, el compilador puede ser más estricto; no he probado esta hipótesis (sin embargo, en caso de que no compile en cualquier caso). Pero, por lo tanto, mi observación de que "podría" señalar un defecto, no es que definitivamente lo haga. :) – Deltics