ПРИМЕЧАНИЕ. Следующий ответ - неверно , начиная с ошибочной предпосылки!Вместо того, чтобы отредактировать всю вещь, чтобы сохранить мои румяна, я оставил ее нетронутой, чтобы комментарии, освещающие ошибку, имели смысл,
Как это можно безопасно поддерживать?
Учитывая(если это то, что вы имеете в виду, и я думаю, что это так):
type
TFoo<T> = class end;
PFoo<T> = ^TFoo<T>;
Тогда, если мы имеем:
var
a, b: TFoo<T>;
p: PFoo<T>;
a := TFoo<String>.Create;
b := TFoo<Integer>.Create;
Тогда допустимы оба следующих условия:
p := @a;
p := @b;
В любой момент времени p может разыменовываться к любому TFoo T , но в любой момент времени он может ссылаться только на конкретный T *.1023 *.Я не вижу какого-либо безопасного для времени механизма компиляции для обеспечения правильного разыменования кода p .
Один из способов обойти эту проблему (не ограничение компилятора, а ограничение попыткичтобы выразить что-либо безопасным для типа способом, для которого безопасность типа просто не может быть выражена), было бы создать специфичные для типа производные этих типов и использовать их.В момент, когда вы хотите разыменовать, вы почти наверняка узнаете тип T :
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
Это возможно даже в Delphi 2010.
Однако, что неприятно, при исследовании этого я обнаружил, что:
p := @a; // Should not compile
действительно компилируется.Что мне кажется неправильным.Очень неправильно.И может указать (еще) на еще один недостаток в реализации обобщений в Delphi.
Здесь будут драконы ...