Dot-Net

F# 中 CLI 事件的 C# 樣式事件訪問器

  • February 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# 中編寫以上內容?

在 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

如果你想觸發,你也可以包裝一個事件。

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-

引用自:https://stackoverflow.com/questions/4964348