Что означает "тип" объявления в 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
Ответы
Ответ 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.
Но он не работает должным образом со всеми типами и бросает внутренние ошибки компилятора для некоторых.