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
- Type Cast Expressions