是否支持Delphi XE中的泛型类型?

csh*_*tor 6 delphi delphi-xe

我在D2010,我必须坚持到64位出来.

使用泛型,不支持指向泛型类型的指针,我发现它们确实非常有用.我在其他地方读过SO(2009年的帖子)巴里凯利爵士认为这可能会在未来发生变化.有谁知道XE是否支持这个?

如果没有,我真的希望他们进入XE2.

谢谢.

Too*_*the 5

在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)

您不能拥有泛型函数,但可以使用泛型方法.

因此,您可以使用泛型指针,但请记住,使用这种脏技术,您没有类型安全性.


Del*_*ics 2

注意:以下答案是错误的,因为它是从一个有缺陷的前提开始的!我没有将整个内容编辑掉以挽救我的脸红,而是将其原封不动地保留下来,以便突出显示错误的评论有意义,

如何才能安全地支持这一点?

鉴于(如果这是你的想法,我认为是这样):

  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 中泛型实现的另一个缺陷。

这里有龙...

  • Delphi 中默认不输入 @ 运算符;这就是为什么你没有得到诊断。使用“{$T+}”打开。此外,原则上在 Delphi 中完全有可能拥有通用指针(尽管它们没有实现)。您的第一组示例代码全部错误。(理论上)“p: PFoo&lt;T&gt;”将与“TFoo&lt;T&gt;”类型的位置的地址兼容,我们在这里讨论的是相同的“T”。因此,如果 p 的类型为 `PFoo&lt;Integer&gt;`,则它将与 `@a` 兼容,且仅与 `a: TFoo&lt;Integer&gt;` 兼容,但不与 `a: TFoo&lt;string&gt;` 兼容。 (2认同)