Class operators

[prev] [prev-tail] [tail] [up]

#### 12.8.8 Class operators

Class operators are slightly different from the operators above in the sense that they can only be used in class expressions which return a class. There are only two class operators, as can be seen in table (12.8).

Table 12.8: Class operators

Operator | Action
is | Checks class type
as | Conditional typecast

An expression containing the is operator results in a boolean type. The is operator can only be used with a class reference or a class instance. The usage of this operator is as follows:

Object is Class

This expression is completely equivalent to

Object.InheritsFrom(Class)

If Object is Nil, False will be returned.

The following are examples:

Var
A : TObject;
B : TClass;
begin
if A is TComponent then ;
If A is B then;
end;

The as operator performs a conditional typecast. It results in an expression that has the type of the class:

Object as Class

This is equivalent to the following statements:

If Object=Nil then
Result:=Nil
else if Object is Class then
Result:=Class(Object)
else
Raise Exception.Create(SErrInvalidTypeCast);

Note that if the object is nil, the as operator does not generate an exception.

The following are some examples of the use of the as operator:

Var
C : TComponent;
O : TObject;
begin
(C as TEdit).Text:='Some text';
C:=O as TComponent;
end;

The as and is operators also work on interfaces (both COM and CORBA). They can be used to check whether an interface also implements another interface as in the following example:

{$mode objfpc}
uses
SysUtils;
type
IMyInterface1 = interface
['{DD70E7BB-51E8-45C3-8CE8-5F5188E19255}']
procedure Bar;
end;
IMyInterface2 = interface
['{7E5B86C4-4BC5-40E6-A0DF-D27DBF77BCA0}']
procedure Foo;
end;
TMyObject = class(TInterfacedObject, IMyInterface1, IMyInterface2)
procedure Bar;
procedure Foo;
end;
procedure TMyObject.Bar;
begin
end;
procedure TMyObject.Foo;
begin
end;
var
i: IMyInterface1;
begin
i := TMyObject.Create;
i.Bar;
Writeln(BoolToStr(i is IMyInterface2, True)); // prints true
Writeln(BoolToStr(i is IDispatch, True)); // prints false
(i as IMyInterface2).Foo;
end.

Additionally, the is operator can be used to check if a class implements an interface, and the as operator can be used to typecast an interface back to the class:

{$mode objfpc}
var
i: IMyInterface;
begin
i := TMyObject.Create;
Writeln(BoolToStr(i is TMyObject,True)); // prints true
Writeln(BoolToStr(i is TObject,True)); // prints true
Writeln(BoolToStr(i is TAggregatedObject,True)); // prints false
(i as TMyObject).Foo;
end.

Although the interfaces must be COM interfaces, the typecast back to a class will only work if the interface comes from an Object Pascal class. It will not work on interfaces obtained from the system by COM.

[prev] [prev-tail] [front] [up]