Resumo sobre is e as

Pascal/FPC operador is verificação de tipo, as conversão segura, TClass(X) conversão bruta forçada sem validação

Uso do is e as

1 Operador is: Detecção de tipo em tempo de execução

Verifica se uma instância de objeto pertence à classe especificada ou às suas subclasses, retorna um valor booleano True/False e é usado para validação prévia segura.

2 Operador as: Conversão de tipo segura

Conversão ascendente / descendente baseada em validação de tipo em tempo de execução; dispara exceção imediatamente em caso de incompatibilidade de tipos, prioriza a segurança.

3 TMyClass(X) conversão bruta forçada (unchecked typecast)

Não executa validação em tempo de execução, reinterpreta a memória de forma forçada diretamente; executa mais rápido, mas causa comportamento indefinido (falhas, chamadas inválidas de métodos, erros de memória) quando os tipos não correspondem. Utilize apenas após confirmar o tipo com is.

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

type
  // Classe base
  TFather = class
    procedure FatherMethod;
  end;

  // Classe derivada que herda 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; // Variável de referência da classe base
begin
  Son := TSon.Create;
  try
    // Instância da classe derivada pode invocar todos os métodos diretamente
    Son.FatherMethod;
    Son.SonMethod;

    // Conversão ascendente: atribuir classe derivada à referência da classe base, sintaticamente válido
    C := Son;
    C.FatherMethod; // Referência da base pode chamar seus próprios métodos

    // C.SonMethod; // Erro de compilação: TFather não possui esse método

    // 1. Verificação de tipo is + conversão segura as
    if C is TSon then
      (C as TSon).SonMethod;

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

Resultado da execução

FatherMethod
SonMethod
FatherMethod
SonMethod

C originalmente é uma referência do tipo TFather C: TFather;, mas aponta para o objeto C := Son;. Subclasses conseguem invocar métodos da classe pai através de C.FatherMethod;,

Para chamar métodos exclusivos da subclasse (C as TSon).SonMethod; é obrigatório realizar a verificação com is primeiro if C is TSon then, evitando erros em tempo de execução.

Comparação entre conversões as e TFather(X)

1. X as TFather

Conversão segura, recomendada para cenários comuns

  • Realiza validação de tipo em tempo de execução internamente, equivalente a executar implicitamente X is TMyClass;
  • Dispara exceção EInvalidCast em caso de tipos incompatíveis, o programa consegue capturar o erro;
  • Possui pequeno custo de desempenho, ignorável para a maioria dos códigos de negócio.

2. TFather(X) conversão forçada bruta

Conversão sem validação, apenas para cenários de alta performance, interpreta a memória de forma direta e forçada.

  • Pula completamente a validação de tipo em tempo de execução, interpreta diretamente o ponteiro do objeto de forma forçada;
  • Executa um pouco mais rápido;
  • Riscos: se X não for instância da classe alvo, chamadas de métodos causam estouro de memória, falha de pilha e exceções aleatórias (comportamento indefinido);
  • Só pode ser usado após verificação prévia com is para garantir correspondência de tipos:
// Forma segura 1: conversão as (uso geral)
if A is TFather then
  (A as  TFather).CallSomeMethodOfFather;

// Forma segura 2: conversão bruta forçada (máximo desempenho, validação is feita antes)
if A is TFather then
  TMyClass(A).CallSomeMethodOfMyClass;Code language: JavaScript (javascript)

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *