According to docs you can implement multiple interfaces with object expressions. But if you see below code :
// Define two interfaces
type IFirst =
abstract F : unit -> unit
abstract G : unit -> unit
type ISecond =
abstract H : unit -> unit
abstract J : unit -> unit
// This object expression implements both interfaces.
let implementer : IFirst =
{ new ISecond with
member this.H() = ()
member this.J() = ()
interface IFirst with
member this.F() = ()
member this.G() = () }
So casting to IFirst
causes a compiler error. Why is that so?
F# does not perform implicit conversions.
When type annotating in a let
binding, the type must strictly match the expression.
For example,
let value : obj = new System.Collections.Generic.List<int>()
will fail to compile, even though a List
is very obviously an object.
When you write:
let implementer : IFirst = expr
The type of expr
must absolutely be IFirst
. There's no implicit casting like in C#.
An object expression will have its type as the abstract type implemented, so:
{ new ISecond with ... }
will be inferred to have a type of ISecond
. Combine it with no-implicit casts rule, and you have a compile error.
Because IFirst
and ISecond
are unrelated, you could (runtime) downcast to IFirst
:
let firstImplementer = implementer :?> IFirst
Another option is to make a combined interface:
type IBoth = inherit IFirst inherit ISecond
and do:
let implementer =
{
new IBoth with ...
That way you can freely (static) upcast to IFirst
or ISecond
.
let firstImplementer = implementer :> IFirst
let secndImplementer = implementer :> ISecond
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With