Zusammenfassung zu is und as

Pascal/FPC is Typabfrage, as sicherer Typumwandlung, TClass(X) ungeprüfte Rohumwandlung

Verwendung von is und as

1 is Operator: Laufzeit-Typerkennung

Prüft, ob eine Objektinstanz zu einer angegebenen Klasse oder deren Unterklassen gehört, gibt einen booleschen Wert True/False zurück und dient der sicheren Vorprüfung.

2 as Operator: Sichere Typumwandlung

Hoch-/Herabumwandlung mit Laufzeit-Typvalidierung; wirft bei Typunterschied direkt eine Ausnahme, Sicherheit hat Vorrang.

3 TMyClass(X) ungeprüfte Rohumwandlung (unchecked typecast)

Keine Laufzeitprüfung, interpretiert den Speicher direkt zwangsweise; schneller in der Ausführung, verursacht aber bei abweichenden Typen undefiniertes Verhalten (Absturz, ungültige Methodenaufrufe, Speicherfehler). Nur nach vorheriger Typbestätigung mit is verwenden.

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

type
  // Basisklasse
  TFather = class
    procedure FatherMethod;
  end;

  // Abgeleitete Klasse, erbt von 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; // Basisklassen-Referenzvariable
begin
  Son := TSon.Create;
  try
    // Instanz der abgeleiteten Klasse kann alle Methoden direkt aufrufen
    Son.FatherMethod;
    Son.SonMethod;

    // Hochumwandlung: Abgeleitete Klasse an Basisklassenreferenz zuweisen, syntaxkonform
    C := Son;
    C.FatherMethod; // Basisklassenreferenz kann eigene Basismethoden aufrufen

    // C.SonMethod; // Kompilierfehler: TFather besitzt diese Methode nicht

    // 1. is-Typabfrage + as-sichere Umwandlung
    if C is TSon then
      (C as TSon).SonMethod;

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

Ausgabe des Programmlaufs

FatherMethod
SonMethod
FatherMethod
SonMethod

C ist ursprünglich eine Referenz vom Typ TFather C: TFather;, verweist aber auf das Objekt C := Son;. Eine Unterklasse kann über die Referenz die Basisklassenmethoden C.FatherMethod; aufrufen.

Um die spezifischen Methoden der Unterklasse (C as TSon).SonMethod; aufzurufen, muss zuerst eine Typabfrage mit is if C is TSon then erfolgen, um Laufzeitfehler zu vermeiden.

Vergleich der Umwandlungen as und TFather(X)

1. X as TFather

Sichere Typumwandlung, empfohlen für normale Anwendungsfälle

  • Führt im Hintergrund eine Laufzeit-Typüberprüfung durch, entspricht einer impliziten Ausführung von X is TMyClass ;
  • Wirft bei Typunterschied eine EInvalidCast-Ausnahme, das Programm kann den Fehler abfangen ;
  • Verursacht geringfügigen Leistungsaufwand, für den meisten Geschäftscode vernachlässigbar.

2. TFather(X) erzwungene Rohumwandlung

Ungeprüfte Direktumwandlung, nur für Hochleistungsfälle gedacht, interpretiert den Speicher ohne Prüfung zwangsweise.

  • Überspringt die Laufzeit-Typüberprüfung vollständig, interpretiert den Objektpointer direkt erzwungen ;
  • Läuft geringfügig schneller ;
  • Gefahr: Wenn X keine Instanz der Zielklasse ist, rufen Methodenaufrufe Speicherzugriffsverletzungen, Stackabstürze und zufällige Ausnahmen hervor (undefiniertes Verhalten) ;
  • Nur zulässig nach vorheriger Prüfung mit is, um passende Typen sicherzustellen :
// Sichere Schreibweise 1: as-Umwandlung (allgemein nutzbar)
if A is TFather then
  (A as  TFather).CallSomeMethodOfFather;

// Sichere Schreibweise 2: ungeprüfte Rohumwandlung (Maximalleistung, vorher is geprüft)
if A is TFather then
  TMyClass(A).CallSomeMethodOfMyClass;Code-Sprache: JavaScript (javascript)

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert