简体   繁体   中英

Multiple parameter event type without boxing in F#

The C# equivalent of what I'd like to declare is simple:

public event Action<DateTime, int> example;

I wish to subscribe to this event from C# as follows:

example += DoSomething;

private static void DoSomething(DateTime time, int count)
{
    Console.WriteLine("Time: {0} Count:{1}", time, count);
}

I can use DelegateEvent ( see this question ), but my understanding is that DelegateEvent.Trigger will result in the boxing of the values, as they're passed in as an object array.

How can I define an event of multiple parameters without boxing in F#?

The concrete implementation of DelegateEvent does box the arguments into an obj[] , but you can create your own IDelegateEvent type instead:

type T() =
    let handlers = ResizeArray<System.Action<System.DateTime,bool>>()
    let event = { new IDelegateEvent<_> with
                        member __.AddHandler(h) = handlers.Add h 
                        member __.RemoveHandler(h) = handlers.Remove h |> ignore }
    [<CLIEvent>]
    member x.example = event
    member x.Trigger(dt,i) =
        for handler in handlers do
            handler.Invoke(dt,i)

If this is something you'll do a lot, then you could encapsulate the logic into its own CustomEvent type rather than spreading it through the type containing the event.

[<Struct>]
type MyEventArgs(date:DateTime,number:int) =
    member x.Date = date
    member x.Number = number

type MyClass() =
    let e = new Event<_>()
    [<CLIEvent>]
    member x.OnEvent = e.Publish
    member private this.FireEvent (s:DateTime) (i:int) = 
        e.Trigger (MyEventArgs(s,i))

Then from C#:

namespace Test
{
  class MainClass
  {
    public static void Main (string[] args)
    {
      MyClass c = new MyClass ();
      c.OnEvent += (object sender, MyLib.EventArgs a) =>   
        Console.WriteLine("Hello from F#");
    }
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM