If you run:
type Car<'T> () = class end
type Mercedes () =
inherit Car<int> ()
let merc = Mercedes ()
and then run each of the following lines, you get the indicated results:
merc :? Mercedes // true
box merc :? Mercedes // true
merc :? Car<int> // error FS0193: types not compatible
box merc :? Car<int> // true
merc :? Car<_> // error FS0193: types not compatible
box merc :? Car<_> // false
- See the first four cases. Why do you need to box
mercfor the test againstCar<int>, but not for the test againstMercedes? - In the last two cases I'm trying to find something that'll return
truebecausemercis aCar, without regard to the type argument. Is there such a thing?
CodePudding user response:
To answer your second question, there is no built-in operator for testing whether a value inherits from a class regardless of a type argument. You can check this using reflection by getting the base type of Mercedes and comparing its generic type definition with the generic type definition of Car<_>:
merc.GetType().BaseType.GetGenericTypeDefinition() = typedefof<Car<_>>
In practice, it may be much easier to introduce a non-generic base class though:
type Car() = class end
type Car<'T> () =
inherit Car()
type Mercedes () =
inherit Car<int> ()
let merc = Mercedes ()
box merc :? Car
To answer your first question, I think the compiler is giving you a hint that the operation is not useful because it will always succeed - so there is no point checking this using :?.
If you instead have a value that has a static type of Car<int> and you want to check whether it is Mercedes, this is alowed, because that is an interesting question to ask:
Car<int>() :? Mercedes
But checking Car<obj>() :? Mercedes is not allowed, because this is statically known to be false.
