Home > Mobile >  F#: How to add event handler in an inherited type
F#: How to add event handler in an inherited type

Time:08-11

I have a base class with an event and an inherited class, where I would like to add a handler, e.g.

type BaseClass() =
    let event = new Event<unit>()

    [<CLIEvent>]
    member t.MyEvent = event.Publish


type Inherited() =
    inherit BaseClass()

    do  base.MyEvent.Add(fun () -> ())

However I get an error on the final line: FS0419 'base' values may only be used to make direct calls to the base implementations of overridden members.

One approach I've tried is using the this instead:

type Inherited() as this =
    inherit BaseClass()

    do  this.MyEvent.Add(fun () -> ())

This does work, however I was wondering if there is a more appropriate solution using an override suggested in the error message?

As I thought there must be a good reason why base.MyEvent.Add... is disallowed - but I don't know the syntax that's needed.

CodePudding user response:

I think the short answer is no. Using this is correct in your example. The need for base arises only when you're overriding a member and want to call the base implementation from the derived type, which isn't the case here.

However, you can make an abstract event like this:

[<AbstractClass>]
type BaseClass() =
    let event = new Event<unit>()

    [<CLIEvent>]
    abstract member MyEvent : IEvent<unit>
    default _.MyEvent = event.Publish

And then reference it via base like this:

type Inherited() =
    inherit BaseClass()

    do base.MyEvent.Add(fun () -> ())

    let otherEvent = new Event<unit>()

    [<CLIEvent>]
    override _.MyEvent = otherEvent.Publish

CodePudding user response:

The answer to this is hidden in subtle implementation details, which are elaborated on by Don Syme in this post:

https://github.com/dotnet/fsharp/issues/9806#issuecomment-679264925

"The workaround is to use add_Event":

    do  base.add_Event (fun _ _ -> ())

CodePudding user response:

Use Composition over Inheritance.

type Base() =
    let event = new Event<unit>()

    [<CLIEvent>]
    member _.MyEvent = event.Publish

type Composition() =
    let b = Base()
    do b.MyEvent.Add(fun _ -> printfn "Called!")

    member _.Base = b
  • Related