What “type of” declaration represents in Delphi and how can it be used

前端 未结 3 1194
死守一世寂寞
死守一世寂寞 2021-02-01 04:23

There is some strange code in Datasnap.DSReflect unit

  TDSAdapterClassType = type of TDSAdapterClass;

  TDSAdapterClass = class(TPersistent)
  pri         


        
相关标签:
3条回答
  • 2021-02-01 05:16

    In Delphi.Net we have the following definitions in SysUtils:

    type
      TInterfaceRef = type of interface;
    
      function Supports(const Instance: TObject; const IID: TInterfaceRef): Boolean; overload; inline;
    

    So it was some kind of replacement for class of that can be used for interface types.

    The following document mentions a "Type reference syntax (type of Interface)": http://edn.embarcadero.com/article/29780

    Here's some more info: http://hallvards.blogspot.de/2004/11/object-to-interface-casts.html

    0 讨论(0)
  • 2021-02-01 05:20

    It's not documented. The behaviour is non-repeatable. Some behaviour feels like class of but we don't need another way to do that. And class of for a value type is nonsensical.

    My conclusion is that this must be a compiler bug. The code is invalid and should be rejected by the compiler. The bug is that the code is accepted instead of being rejected.

    As can be seen from Hallvard Vassbotn's article, type of is a feature of the Delphi .net compiler that creates types that map to .net's System.RuntimeTypeHandle type. Loosely speaking therefore, type of provides for functionality equivalent to the C# typeof operator.

    My best guess is that the Delphi desktop compiler accepts type of when it should not, as a vestige of the .net compiler.

    0 讨论(0)
  • 2021-02-01 05:23

    It seems to be related to PTypeInfo based in the TypeKind as you can write this:

    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.
    

    But it does not work properly with all types and throws internal compiler errors for some.

    0 讨论(0)
提交回复
热议问题