Is there any reason why you can't use "is" to check type compatibility between interfaces? You can use it between object references, interfaces to objects, just not interfaces to interfaces.

Is there any reason why you can't use "is" to check type compatibility between interfaces?  You can use it between object references, interfaces to objects, just not interfaces to interfaces.

Consider:

type
  IInterfaceA = interface
   // GUID here
  end;
  IInterfaceB = interface(IInterfaceA)
  // GUID here
  end;

var
  IA : IInterfaceA;
  IB : IInterfaceB;
begin
  IB := GetIB;
  if IB is IInterfaceA then
    IA := IB; // or IA := IB as IA;
end;

This doesn't compile: "E2015 Operator not applicable to this operand type" on the line "if IB is IInterfaceA". But, while you can use "as", on Win-native "as" will throw an exception if it can't convert.  On .Net I think from memory it returned nil - more useful, because then at least you can test "is" via "if Assigned(IB as IA)".

In the end, you need to use Supports:
  if Supports(IB, IInterfaceA, MyIInterfaceAVar) then...
which requires an extra variable and looks clumsy.  And as far as I know it's the only way to do it.

Serious question here: why?  And is there a cleaner way than Supports?  You can check object classes this way, as well as interfaces to objects - just not interfaces to interfaces.  Have I missed something where this is possible?

Comments

  1. Fabian S. Biehn I was unclear, sorry. _IsInterface is an imaginary System.pas method analogous to _IsClass, my idea being that "is" could call either depending on the types with which it's called. Ie, the fact it calls +IsClass is the reason why it doesn't work with interfaces, but it's not a reason why it could not. I can't think of a technical or correctness reason why it couldn't work, which is why I asked the question.

    ReplyDelete
  2. David Millington Haha, actually I hadn't, I just tried to avoid a car analogy :)

    ReplyDelete

Post a Comment