问题
I am exposing an event from F# to C# like this:
let event = new DelegateEvent<EventHandler>()
member x.Ping() = event.Trigger([| x; EventArgs.Empty |])
[<CLIEvent>]
member x.PingEvent = event.Publish
But I'd like some code to run whenever handlers are added or removed. I think this can be done in C# like this:
public event EventHandler PingEvent
{
add
{
//do something
}
remove
{
//do something
}
}
How do I write the above in F#?
回答1:
In F#, you can define events with implementations of the IDelegateEvent<_>
interface (or the IEvent<_>
or IEvent<_,_>
interfaces which derive from it). So you can do something like this:
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:
You could also wrap an event if you wanted triggering.
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"
output
1 first
2 second
-2 second-
来源:https://stackoverflow.com/questions/4964348/c-style-event-accessors-for-cli-events-in-f