0

Does the instruction myVar is TMyObj can work if myVar is nil? I don't know how the is is performed internally

zeus
  • 12,173
  • 9
  • 63
  • 184

2 Answers2

10

It works if myVar is of type TMyObj or a descendant, but returns false if the object is nil.

See The is Operator: (emphasis mine)

The is operator, which performs dynamic type checking, is used to verify the actual runtime class of an object. The expression:

object is class

returns True if object is an instance of the class denoted by class or one of its descendants, and False otherwise. (If object is nil, the result is False.) If the declared type of object is unrelated to class -- that is, if the types are distinct and one is not an ancestor of the other -- a compilation error results.

Community
  • 1
  • 1
LU RD
  • 34,438
  • 5
  • 88
  • 296
1

The implementation of is is available in the system unit.

function _IsClass(const Child: TObject; Parent: TClass): Boolean;
begin
  Result := (Child <> nil) and Child.InheritsFrom(Parent);
end;

Though, it is not 100% reliable because there is some compiler magic surrounding the is operator.

Amongs other, the following :

var
  vWin : TWinControl;
begin
  vWin := TWinControl(TControl.Create(nil));
  if vWin is TWinControl then
    ShowMessage('The shouldn''t be true!!!');
  vWin.Free;
end;

Gets optimised to (at least in Seattle)

var
  vWin : TWinControl;
begin
  vWin := TWinControl(TControl.Create(nil));
  if vWin <> nil then
    ShowMessage('The shouldn''t be true!!!');
  vWin.Free;
end;

Which doesn''t give the result one could expect.

Note : I'm not pretending here that vWin := TWinControl(TControl.Create(nil)) is a valid operation.

Ken Bourassa
  • 6,363
  • 1
  • 19
  • 28
  • 1
    I don't care for this answer. That is actually not the implementation of is. That's the part for object references. But there are also interfaces to consider. And then there's the magic. A good answer here refers to the documentation. – David Heffernan Feb 04 '19 at 21:01
  • I think otherwise. IMO The optimization in this case is open for discussion, vWin clearly does NOT point to a TWinControl object, so the is operator should return False, where the optimized code just checks for assignment. I learned something. – H.Hasenack Feb 05 '19 at 21:56
  • @H.Hasenack The optimisation assume a TWinControl variable will always contains a TWinControl or nil... something I agree on. It is totally fair to consider assigning a TControl in a TWinControl an invalid operation. Though, I don't remember reading any official statement in the documentation to that regard... – Ken Bourassa Feb 07 '19 at 14:21
  • @Ken, exactly. Thats what I learned! Its the choice the optimizer makes. Now I wonder what happens if you turn optimization off... Optimization on/off should NOT change the way the code works, but it might have an effect here. (didn't test) – H.Hasenack Feb 08 '19 at 08:19
  • @H.Hasenack Optimization should not change DEFINED behavior... but it is free to alter any undefined behavior. So, if assigning a non TWincontrol to a TWinControl variable is considered "undefined behavior", the optimization is entirely legitimate. – Ken Bourassa Feb 08 '19 at 18:18
  • @Ken, as I said before, you are right. If I find the time, I'll just try it out to satisfy my curiosity :p – H.Hasenack Feb 08 '19 at 23:06