2

I have tried to call an abstract function from a method's own implementation.

[<AbstractClass>]
type CallAnAbstract () = 

    let doSomethingElse () = printfn "Done Something.."

    abstract doSomethingAbstract: unit -> unit

    member this.DoSomething =
        printfn "Done Something.."
        doSomethingElse ()
        doSomethingAbstract ()

which results in the error:

error FS0039: The value or constructor 'doSomethingAbstract' is not defined

Is calling an abstract function from a method's own implementation illegal or does the problem lie somewhere else?

If that being illegal is the case, here (see answer) @Mark Seemann explains composition over inheritance:

[<AbstractClass>]
type UseComposition (doSomethingElseDefinedLater) = 

    let doSomethingElse () = printfn "Done Something.."

    member this.DoSomething =
        printfn "Done Something.."
        doSomethingElse ()
        doSomethingElseDefinedLater ()

What are the alternatives? I'd avoid passing the function via constructor and I'd like to reuse the some code, having DoSomething have "some implementation" until the call to the abstract function.

Community
  • 1
  • 1
NoIdeaHowToFixThis
  • 4,484
  • 2
  • 34
  • 69

1 Answers1

5

You need to use a this reference:

this.doSomethingAbstract()
Daniel
  • 47,404
  • 11
  • 101
  • 179
  • Ah, ok. Thanks. I thought only `members` required to be referenced that way. – NoIdeaHowToFixThis Mar 10 '14 at 16:16
  • 2
    It is an `abstract` _member_. – Daniel Mar 10 '14 at 16:18
  • It is `private` and it has not been declared using `abstract member`. Isn't that an `abstract` *method*? – NoIdeaHowToFixThis Mar 10 '14 at 16:24
  • 1
    Not sure of the precise definition, but I suspect anything defined with the keyword `member` is a member. That would include properties and methods. – Daniel Mar 10 '14 at 16:28
  • Well, `abstract doSomethingAbstract: unit -> unit` is not declared with the keyword `member` and behaves differently than `abstract member doSomethingAbstract: unit -> unit`. I am not sure either how to refer to `doSomethingAbstract` as per the first definition. – NoIdeaHowToFixThis Mar 10 '14 at 16:31
  • Interestingly enough, `let doSomethingElse () = printfn "Done Something.."` does not require a `this` reference. – NoIdeaHowToFixThis Mar 10 '14 at 16:33
  • My mistake: `abstract doSomethingAbstract: unit -> unit` and `abstract member doSomethingAbstract: unit -> unit` are indeed the same. – NoIdeaHowToFixThis Mar 10 '14 at 16:56
  • 2
    `let` bindings can't be called with a `this` reference, only members. True, an `abstract` member definition doesn't include the keyword `member`, but an override or default implementation does. – Daniel Mar 10 '14 at 16:56