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?
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?
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.
ReplyDeleteDavid Millington Haha, actually I hadn't, I just tried to avoid a car analogy :)
ReplyDelete