The is
operator takes an object instance on the left and a type on the right, and checks whether the object is an instance of the type (or any subtype of the type).
The tests Object is bool
and dynamic is bool
both give false, because you are testing whether a Type object is an instance of bool. If you wrote Object is Type
, it would be true.
The isSubtypeOf
tests give the expected results: Object is not a subtype of bool, and dynamic is a subtype of bool. The dynamic "type" is both a subtype and a supertype of all types according to the <:
relation.
Personally I don't see dynamic
as a type, as much as an alternative to having a type. It's the programmer's way of saying "trust me, I know what I am doing", which is why any test involving dynamic will generally say "yes". It represents some type, or types, that the programmer omitted to write, but which would be perfectly correct if they were there.
As for the title question, the relation is:
(reflect(o).type.isSubtypeOf(reflectType(Foo))) == (o is Foo)