我在D2010,我必须坚持到64位出来.
使用泛型,不支持指向泛型类型的指针,我发现它们确实非常有用.我在其他地方读过SO(2009年的帖子)巴里凯利爵士认为这可能会在未来发生变化.有谁知道XE是否支持这个?
如果没有,我真的希望他们进入XE2.
谢谢.
在XE(2011):
这有效:
type
TTest1<T> = record
FX : T;
end;
TTest2<T> = array of T;
Run Code Online (Sandbox Code Playgroud)
这不起作用:
type
TTest3<T> = ^TTest1<T>;
TTest4<T> = ^TTest2<T>;
TTest<T> = ^T;
Run Code Online (Sandbox Code Playgroud)
因此,指向泛型的指针尚不可能.
但是你可以做到以下几点:
type
TMyClass = class
public
class function GetAddr<T>(const AItem: T): Pointer;
class function GetP<T>(const APtr: Pointer): T;
end;
class function TMyClass.GetAddr<T>(const AItem: T): Pointer;
begin
Result := @AItem;
end;
class function TMyClass.GetP<T>(const APtr: Pointer): T;
begin
Result := T(APtr^);
end;
Run Code Online (Sandbox Code Playgroud)
您不能拥有泛型函数,但可以使用泛型方法.
因此,您可以使用泛型指针,但请记住,使用这种脏技术,您没有类型安全性.
注意:以下答案是错误的,因为它是从一个有缺陷的前提开始的!我没有将整个内容编辑掉以挽救我的脸红,而是将其原封不动地保留下来,以便突出显示错误的评论有意义,
如何才能安全地支持这一点?
鉴于(如果这是你的想法,我认为是这样):
type
TFoo<T> = class end;
PFoo<T> = ^TFoo<T>;
Run Code Online (Sandbox Code Playgroud)
那么如果我们有:
var
a, b: TFoo<T>;
p: PFoo<T>;
a := TFoo<String>.Create;
b := TFoo<Integer>.Create;
Run Code Online (Sandbox Code Playgroud)
那么以下两种情况都是允许的:
p := @a;
p := @b;
Run Code Online (Sandbox Code Playgroud)
在任何给定时间p可能会取消引用T 的任何 TFoo,但在任何给定时间它只能引用特定的T。我看不到任何类型安全的编译时机制来确保代码正确取消引用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
Run Code Online (Sandbox Code Playgroud)
即使在 Delphi 2010 中这也是可能的。
然而,令人担忧的是,在调查过程中我发现:
p := @a; // Should not compile
Run Code Online (Sandbox Code Playgroud)
实际上可以编译。我觉得这是错误的。非常错误。并且可能指出 Delphi 中泛型实现的另一个缺陷。
这里有龙...