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 TMyClassfirst; - Throws
EInvalidCastexception 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
Xis not an instance of target class, method calls cause memory out-of-bounds, stack crash, random exceptions (undefined behavior); - Only permitted after preceding
ischeck 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)