Подтвердить что ты не робот

Что означает "тип" объявления в Delphi и как его можно использовать

В Datasnap.DSReflect unit

есть странный код:
  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

4b9b3361

Ответ 1

Это не задокументировано. Поведение не повторяется. Некоторое поведение похоже на class of, но нам не нужен другой способ сделать это. И class of для типа значения является бессмысленным.

Мое заключение заключается в том, что это ошибка компилятора. Код недействителен и должен быть отклонен компилятором. Ошибка заключается в том, что код принимается вместо отклонения.

Как видно из статьи Hallvard Vassbotn type of - это функция компилятора Delphi.net, которая создает типы, на которые ссылаются .NET System.RuntimeTypeHandle. Таким образом, type of, следовательно, имеет функциональность, эквивалентную оператору С# typeof.

Мое лучшее предположение заключается в том, что компилятор рабочего стола Delphi принимает type of, когда он не должен, в качестве остатка компилятора .net.

Ответ 2

В 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

Ответ 3

Кажется, что это связано с PTypeInfo, основанным на TypeKind, поскольку вы можете написать это:

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.

Но он не работает должным образом со всеми типами и бросает внутренние ошибки компилятора для некоторых.