12.8.7 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 2 class operators, as can be seen in table (12.8).


Table 12.8: Class operators

OperatorAction


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 COM interfaces. 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 varas 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.