is and as Summary

Pascal/FPC is Type Check, as Safe Cast, TClass(X) Unchecked Raw Cast

Usage of is and as

1 is Operator: Runtime Type Detection

Check whether an object instance belongs to a specified class or its descendant classes, returns a Boolean value True/False, used for pre-safety verification.

2 as Operator: Safe Type Cast

Upcasting / Downcasting based on runtime type validation; throws an exception directly if type mismatch, prioritizes safety.

3 TMyClass(X) Unchecked Raw Cast

No runtime validation, directly reinterprets memory forcibly; faster execution speed, but will trigger undefined behavior (crash, invalid method invocation, memory errors) when types mismatch. Only use after confirming the type with is.

program Demo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$codepage utf8}
uses
  SysUtils;

type
  // Base Class
  TFather = class
    procedure FatherMethod;
  end;

  // Derived Class inheriting TFather
  TSon = class(TFather)
    procedure SonMethod;
  end;

procedure TFather.FatherMethod;
begin
  WriteLn('FatherMethod');
end;

procedure TSon.SonMethod;
begin
  WriteLn('SonMethod');
end;

var
  Son: TSon;
  C: TFather; // Base class reference variable
begin
  Son := TSon.Create;
  try
    // Derived class instance can call all methods directly
    Son.FatherMethod;
    Son.SonMethod;

    // Upcasting: Assign derived class to base class reference, grammatically valid
    C := Son;
    C.FatherMethod; // Base reference can invoke base-only methods

    // C.SonMethod; // Compile error: TFather does not contain this method

    // 1. is Type Check + as Safe Cast
    if C is TSon then
      (C as TSon).SonMethod;

  finally
    FreeAndNil(Son);
  end;
end.Code language: JavaScript (javascript)

Execution Output

FatherMethod
SonMethod
FatherMethod
SonMethod

C is originally a reference of type TFather C: TFather;, but it points to the object instance C := Son;. Subclass instances can call base class methods via the reference C.FatherMethod;,

To invoke subclass methods (C as TSon).SonMethod; , you must first perform an is check if C is TSon then to avoid runtime errors.

Comparison between as and TFather(X) Casting

1. X as TFather

Safe casting, recommended for general scenarios

  • Performs runtime type check underneath, equivalent to implicitly executing X is TMyClass first;
  • Throws EInvalidCast exception on type mismatch, which can be caught by program logic;
  • Slight performance overhead, negligible for most business code.

2. TFather(X) Unchecked Raw Cast

No validation raw cast, only for high-performance scenarios, force direct memory reinterpretation.

  • Skips runtime type validation entirely, forcibly interprets object pointer directly;
  • Slightly faster execution;
  • Risks: If X is not an instance of target class, method calls cause memory out-of-bounds, stack crash, random exceptions (undefined behavior);
  • Only permitted after preceding is check to guarantee matching type:
// Safe Approach 1: as Cast (General Use)
if A is TFather then
  (A as  TFather).CallSomeMethodOfFather;

// Safe Approach 2: Unchecked Raw Cast (Max Performance, Preceding is Checked)
if A is TFather then
  TMyClass(A).CallSomeMethodOfMyClass;Code language: JavaScript (javascript)

Leave a Reply

Your email address will not be published. Required fields are marked *