7

Given an F# type:

type Foo() =
    member this.Prop with get() = ()

    interface IDisposable with
        member this.Dispose() = ()

In C#, I create the object, but I can't call Dispose():

var x = new Foo();
x.Dispose(); // compile error, x does not contain a definition of Dispose

However, I can write:

((IDisposable)x).Dispose(); // works, but I don't like the cast

Is there any way to avoid the cast in C#? Is this related to the way F# doesn't automatically let you call .Dispose() on the Foo type from within F#?

ildjarn
  • 62,044
  • 9
  • 127
  • 211
Neil Mitchell
  • 9,090
  • 1
  • 27
  • 85

2 Answers2

16

Interface implementations in F# are explicit by default. Hence the methods are not visible unless seen from the type converted to the interface (some form of casting).

To work around this expose an instance method which has the same signature as the interface version. Then have the interface on forward to the instance function. For example

type Foo() =
    member this.Prop with get() = ()
    member this.Dispose() = ()

    interface IDisposable with
        member this.Dispose() = this.Dispose()
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • 1
    One more reason for me (and everybody else) not to do OOP in F# :) – Ankur Oct 18 '11 at 04:11
  • 2
    I dont think thats a reason not to use OOP in F#. Using OOP in F# should be a design decision based on complexity of the project and the overall design. – 7sharp9 Oct 18 '11 at 11:07
  • 2
    Is there any rationale behind this decision, or was it because of backwards compatibilty to OCaml? In my mind, when a Student 'is a' Person, I would assume the Student has an age I can just ask for without having to cast to IPerson first. Do you know why this was implemented like this? – gjvdkamp Dec 21 '11 at 12:20
3

How about, for this particular interface:

using (var x = new Foo()) {
    ...
}
Daniel
  • 47,404
  • 11
  • 101
  • 179