I'm trying to get a grip on F#, and in the process I am converting some C# code. I'm having some trouble with defining properties in an interface and implementing them in a type.
Consider the following code:
module File1
type IMyInterface =
abstract member MyProp : bool with get, set
abstract member MyMethod : unit -> unit
type MyType() =
interface IMyInterface with
member val MyProp = true with get, set
member self.MyMethod() = if MyProp then () else ()
The documentation for F# properties appears to state that my implementation of MyProp in MyType is correct, however, the compiler complains that "The value or constructor 'MyProp' is not defined". Any ideas?
To access the property within an (explicit) interface you need to cast to the self
reference to the interface type:
type MyType() =
interface IMyInterface with
member val MyProp = true with get, set
member self.MyMethod() = if (self :> IMyInterface).MyProp then () else ()
You get the same error in C# if you implement the interface explicitly, and a cast is also required to access the member:
interface IMyInterface
{
bool MyProp { get; set; }
void MyMethod();
}
class MyType : IMyInterface
{
bool IMyInterface.MyProp { get; set; }
void IMyInterface.MyMethod()
{
if (((IMyInterface)this).MyProp) { }
}
}
If you are only accessing the interface, then you don't need to define members in the type itself. Phil's answer is good if you want minimalism, but another approach I like is to use "let-bound" values rather than members -- for more complex code, type inference is better and they are generally easier to deal with than members.
type MyType() =
let mutable myProp = true
let myMethod() = if myProp then () else ()
interface IMyInterface with
member __.MyProp with get() = myProp and set v = myProp <- v
member __.MyMethod() = myMethod()
The code is slightly cleaner than member versions as well, imo, because the self
tag in type MyType() as self
is only needed to access members -- let-bound values can be accessed directly from the interface.
here is a working version:
type IMyInterface =
abstract member MyProp : bool with get, set
abstract member MyMethod : unit -> unit
type MyType() =
member val MyProp = true with get, set
member self.MyMethod() = if self.MyProp then () else ()
interface IMyInterface with
member self.MyProp with get () = self.MyProp and set v = self.MyProp <- v
member self.MyMethod() = self.MyMethod()
please note that I included the explicit members as you surely would have missed them ;)
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