Delphi中"声明类型"的含义以及如何使用它

Dal*_*kar 24 delphi

有一些奇怪的代码Datasnap.DSReflect单元

  TDSAdapterClassType = type of TDSAdapterClass;

  TDSAdapterClass = class(TPersistent)
  private
    FAdapteeInstance: TObject;
  public
    constructor Create(AdapteeInstance: TObject); virtual;
  end;
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它

var
  AdapteeInstance: TObject;
  FClassRef: TPersistentClass;

  Result := TDSAdapterClassType(FClassRef).Create(AdapteeInstance);
Run Code Online (Sandbox Code Playgroud)

乍一看,它似乎就像宣布类引用的另一种方式.但逻辑意味着在不增加更多功能的情况下引入语言构造的这种变体是没有意义的.遵循该逻辑我发现以下声明编译:

type
  TypeOfInteger = type of Integer;
  TypeOfByte = type of Byte;

  TRec = record
    x: integer;
  end;
  TypeOfTRec = type of TRec;

  TBytes = array of byte;
  TypeOfTBytes = type of TBytes;
Run Code Online (Sandbox Code Playgroud)

有趣的是,以下声明无法编译.

type
  TypeOfString = type of String;
Run Code Online (Sandbox Code Playgroud)

所以问题是type of实际代表什么以及它如何在现实生活中应用,除了作为某种别名class of

注意: type of在Delphi 7中没有编译,似乎它是后来介绍的,它最终在XE中存在,但是我没有安装Delphi 2007-2010来尝试它.

更新:我已填写错误报告https://quality.embarcadero.com/browse/RSP-9850

Seb*_*n Z 6

在Delphi.Net中,我们在SysUtils中有以下定义:

type
  TInterfaceRef = type of interface;

  function Supports(const Instance: TObject; const IID: TInterfaceRef): Boolean; overload; inline;
Run Code Online (Sandbox Code Playgroud)

因此它class of可以用于接口类型的某种替代.

以下文档提到了"类型引用语法(接口类型)":http: //edn.embarcadero.com/article/29780

以下是一些更多信息:http: //hallvards.blogspot.de/2004/11/object-to-interface-casts.html


Ste*_*nke 5

它似乎与基于TypeKind的PTypeInfo有关,因为你可以这样写:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TIntType = type of Integer;
  TInt64Type = type of Int64;

var
  intType: TIntType;
  int64Type: TInt64Type;
begin
  try
    intType := Integer;
    Assert(Pointer(intType) = TypeInfo(Integer));
    intType := Cardinal;
    Assert(Pointer(intType) = TypeInfo(Cardinal));
    intType := NativeInt;
    Assert(Pointer(intType) = TypeInfo(NativeInt));
    int64Type := Int64;
    Assert(Pointer(int64Type) = TypeInfo(Int64));
    int64Type := UInt64;
    Assert(Pointer(int64Type) = TypeInfo(UInt64));
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.
Run Code Online (Sandbox Code Playgroud)

但它对所有类型都不能正常工作,并且会为某些类型引发内部编译器错误.


Dav*_*nan 2

这没有记录。该行为是不可重复的。有些行为感觉很像class of,但我们不需要其他方法来做到这一点。对于class of值类型来说是无意义的。

我的结论是这一定是编译器错误。该代码无效,应被编译器拒绝。错误在于代码被接受而不是被拒绝。

从 Hallvard Vassbotn 的文章中可以看出,type ofDelphi .net 编译器的一个功能是创建映射到 .netSystem.RuntimeTypeHandle类型的类型。因此,宽松地说,type of它提供了与 C#typeof运算符等效的功能。

我最好的猜测是,Delphi 桌面编译器type of在不应该接受的时候接受了,这是 .net 编译器的残余。

  • 从到目前为止我所能收集到的一切来看,这是正确的答案。“type of”是过去的遗物,不是可用的功能。然而,赏金转到另一个答案,该答案提供了“type of”的来源信息。 (2认同)