Sealed types are a .NET concept. They are types that cannot be inherited from. This includes:
- F# records
- F# unions
- F# classes declared with the
[<Sealed>]
attribute - C# classes declared with the
sealed
keyword
Now, the :?
operator tests whether a value is an instance of a given type. For example, if a variable a
has statically known type T
, and U
is a subtype of T
, then a :? U
checks whether a
is type U
. It's false if a
is a concrete T
or another subtype of T
.
But if T
is sealed, then it has no subtype. So the expression a :? U
is trivially false. Unless U
is T
or a supertype of T
, in which case it's trivially true. Either way, it's a useless test. So the F# compiler assumes you made a mistake.
The expression box a
, on the other hand, upcasts a
to type obj
. This type is not sealed (obviously, since all other types inherit from it). So there's nothing wrong with using :?
on it.