Type Check Expressions

The is and is not type check expressions can be used to check if a concrete class instance is compatible with a given type – i.e. is of that type or descendant, or implement the given interface. This is most useful with polymorphism, when a valuen is declares as a base type, and the concrete type it might hold is not known at compile-time.

var p: Person := FindPersonByName("Peter Parker");

if p is Employee then begin
  ...
end;

The above example assumes a class hierarchy, where Exployee is a subclass of the Person class. the FindPersonByName method might be declared to return any ind of person, and the is check is used to determine if the returned instance is of type Employee, or not.

The expression p is Employee will evaluate as true if the instance het by p is of type Employee, or any further subclass of Employee. It will be false, otherwise *e.e.g id p holds Client persion instance.

is can also be used to determine of a class implements a given interface:

if p is IDisposable then begin
  ...
end;

Note that the compiler will emit a hint if it can determine a given is check to always be false (or always be true), at compile time, for example, because the two types are from incompatible subtrees of the class hierarchy, or from differen TObject models:

var p: Person := FindPersonByName("Peter Parker");

if p is Button then begin // Hint: will always be false, compiler knows a Person can't be a Button
  ...
end;

If the source value is nil, an is type check will always evaluate to false.

Negative is not Checks

While, like any boolean expression, an is type check can be negated by not, a special is not expression is supported to allow a more convenient and readable negative check:

var p: Person := FindPersonByName("Peter Parker");

if p is not Manager then begin
  ...
end;

is equivalent to the more verbose and less intuitive:

if not (p is Manager) then begin
  ...
end;

If the source value is nil, an is not type check will always evaluate to true, correctly negating the behavior of is.

Inline Variable Declarations

An is type check can optionally declare a new inline variable matching the new type, which will be assigned by Type Casting the source value to the target type if it matches. Otherwise the new variable will be nil. The new variable will valid for the remainder of the current scope.

if p is var e: Employee then begin
  e.GiveRaise; // e is always assigned, here
end;
writeLn($'was employee? {assigned(e)}"); // e is still valid here, but may be nil

would be equivalent to:

if p is Employee then begin
  var e:= o as Employee;
  e.GiveRaise;
end;

See Also