Pascal/FPC is 类型判断、as 安全转换、TClass(X) 强制裸转换
is 和as的使用
1 is 运算符:运行时类型检测
判断对象实例是否属于指定类 / 其子类,返回布尔值 True/False,用于安全前置校验。
2 as 运算符:安全类型转换
基于运行时类型校验的向上 / 向下转型;类型不匹配时直接抛出异常,安全优先。
3 TMyClass(X) 裸强制转换(unchecked typecast)
无运行时校验,直接强行 reinterpret 内存;速度更快,但类型不符时会出现未定义行为(崩溃、乱调用、内存错误),仅在已用 is 确认类型后使用。
program Demo;
{$ifdef FPC} {$mode objfpc}{$H+}{$J-} {$endif}
{$ifdef MSWINDOWS} {$apptype CONSOLE} {$endif}
{$codepage utf8}
uses
SysUtils;
type
// 基类
TFather = class
procedure FatherMethod;
end;
// 派生类,继承 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; // 基类引用变量
begin
Son := TSon.Create;
try
// 派生类自身可直接调用所有方法
Son.FatherMethod;
Son.SonMethod;
// 向上转型:派生类赋值给基类引用,语法合法
C := Son;
C.FatherMethod; // 基类引用可调用基类自有方法
// C.SonMethod; // 编译报错:TFather 无此方法
// 1. is 判断类型 + as 安全转换
if C is TSon then
(C as TSon).SonMethod;
finally
FreeAndNil(Son);
end;
end.Code language: JavaScript (javascript)
运行结果
FatherMethod
SonMethod
FatherMethod
SonMethod

C是本来是一个TFather的引用C: TFather;,但是指向的对象是C := Son;,子类可以调用父类方法C.FatherMethod;,
如果要调用子类方法(C as TSon).SonMethod; 则需要先进行is判断if C is TSon then,这样避免报错。
as 与 TFather(X) 转换对比
1. X as TFather
TFather安全转换,推荐常规场景
- 底层执行运行时类型校验,等价于先隐式执行
X is TMyClass; - 类型不匹配 → 抛出
EInvalidCast异常,程序可捕获错误; - 有微小性能开销,绝大多数业务代码可忽略。
2. TFather(X) 强制类型转换
无校验裸转换,仅高性能场景,直接暴力转换。
- 完全跳过运行时类型检查,直接强制解释对象指针;
- 速度略快;
- 风险:若
X实际不是目标类实例,调用方法会内存越界、栈崩溃、随机异常(未定义行为); - 仅允许搭配
is判断后使用,确保类型一定匹配:
// 安全写法1:as 转换(通用)
if A is TFather then
(A as TFather).CallSomeMethodOfFather;
// 安全写法2:裸强制转换(极致性能,已前置is校验)
if A is TFather then
TMyClass(A).CallSomeMethodOfMyClass;Code language: JavaScript (javascript)
Previous: 构造函数和析构函数
Next: 属性(Property)