Средства доступа к событиям в стиле C # для событий CLI в F # - PullRequest
9 голосов
/ 11 февраля 2011

Я выставляю событие из F # в C # следующим образом:

let event = new DelegateEvent<EventHandler>()
member x.Ping() = event.Trigger([| x; EventArgs.Empty |])
[<CLIEvent>]
member x.PingEvent = event.Publish

Но я бы хотел, чтобы какой-нибудь код запускался всякий раз, когда добавляются или удаляются обработчики.Я думаю, что это можно сделать в C # следующим образом:

public event EventHandler PingEvent
{
    add 
    {
        //do something
    }
    remove
    {
        //do something
    }
}

Как мне написать выше в F #?

Ответы [ 2 ]

11 голосов
/ 11 февраля 2011

В F # вы можете определять события с реализациями интерфейса IDelegateEvent<_> (или интерфейсов IEvent<_> или IEvent<_,_>, которые вытекают из него).Таким образом, вы можете сделать что-то вроде этого:

let customEvent add remove =
  { new IDelegateEvent<_> with
        member this.AddHandler del = add del
        member this.RemoveHandler del = remove del }

type MyType() =
  let ev = customEvent (* your add handler *) (* your remove handler *)

  [<CLIEvent>]
  member this.myEvent = ev
2 голосов
/ 11 февраля 2011

Вы также можете обернуть событие, если хотите запустить.

type MonitoredEvent<'a>(add, remove) =
    inherit Event<'a>() 

    let bp = base.Publish
    let p = { new IEvent<'a> with 
                member this.AddHandler del = 
                    add()
                    bp.AddHandler del
                member this.RemoveHandler del = 
                    remove()
                    bp.RemoveHandler del
                member this.Subscribe o = 
                    failwith "Not implemented"
                }

    member this.Publish = p

type Something() =
    let mutable listeners = 0
    let add() = listeners <- listeners + 1
    let remove() = listeners <- listeners - 1
    let me = new MonitoredEvent<_>(add, remove)

    member this.Ping x = me.Trigger (sprintf "%d %s" listeners x)

    [<CLIEvent>]
    member this.PingEvent = me.Publish

let computer = new Something()
computer.PingEvent.Add(printfn "%s")
computer.Ping "first"
computer.PingEvent.Add(printfn "-%s-")
computer.Ping "second"

выход

1 first
2 second
-2 second-
...