什么"类型"声明在Delphi中表示,如何使用它

时间:2014-12-18 20:38:17

标签: delphi

Datasnap.DSReflect单位

中有一些奇怪的代码
  TDSAdapterClassType = type of TDSAdapterClass;

  TDSAdapterClass = class(TPersistent)
  private
    FAdapteeInstance: TObject;
  public
    constructor Create(AdapteeInstance: TObject); virtual;
  end;

然后像这样使用

var
  AdapteeInstance: TObject;
  FClassRef: TPersistentClass;

  Result := TDSAdapterClassType(FClassRef).Create(AdapteeInstance);

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

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;

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

type
  TypeOfString = type of String;

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

的某种别名之外

注意: type of无法在Delphi 7中编译,似乎稍后会介绍,它在XE中确实存在,但我没有Delphi 2007 -2010安装在那里尝试。

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

3 个答案:

答案 0 :(得分:6)

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

type
  TInterfaceRef = type of interface;

  function Supports(const Instance: TObject; const IID: TInterfaceRef): Boolean; overload; inline;

因此它可以替代class of,可以用于接口类型。

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

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

答案 1 :(得分: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.

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

答案 2 :(得分:2)

没有记录。这种行为是不可重复的。有些行为感觉像class of,但我们不需要另外的方式来做到这一点。而class of对于值类型则是无意义的。

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

从Hallvard Vassbotn的article可以看出,type of是Delphi .net编译器的一个功能,可以创建映射到.net的{{3} {{3} }类型。因此,松散地说,type of提供了与C#typeof运算符等效的功能。

我最好的猜测是Delphi桌面编译器在不应该接受type of时,作为.net编译器的遗迹。