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).
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.