Create an action in F# in order to use a c# method

人走茶凉 提交于 2020-01-24 21:22:19

问题


I would like to use this method from Owin implementation of HttpListener :

public static IDisposable Create(AppFunc app, IDictionary<string, object> properties)

AppFunc has a signature like this :

IDictionnary<string,Object> -> Task

I wanted to create a task but it requires an action, and I failed to know how to do it in F#. The best I managed so far was using the code in this question :

module CsharpAction

open System

type Wrapper<'T>(f:'T -> unit) =
      member x.Invoke(a:'T) = f a

let makeAction (typ:Type) (f:'T -> unit) = 
    let actionType = typedefof<Action<_>>.MakeGenericType(typ)
    let wrapperType = typedefof<Wrapper<_>>.MakeGenericType(typ)
    let wrapped = Wrapper<_>(f)
    Delegate.CreateDelegate(actionType, wrapped, wrapped.GetType().GetMethod("Invoke"))

program.fs

let yymmdd1 (date:DateTime) = date.ToString("yy.MM.dd")
    let printSuccess = fun() -> printfn "Success %s" (yymmdd1 DateTime.Now )
    let actionTask = CsharpAction.makeAction (typeof<string>) (printSuccess)
    let mutable properties = Dictionary(dict [("fooKey", new Object())])


    let server = OwinServerFactory.Create((fun (props) -> new  Task(actionTask)) , properties)

but then it tells me : this expression was expected to have type action but here has type delegate

Should I give from F# an action to c# code? or should I work on the c# code in order to give f# some niceties , for instance waiting for delegate instead of action ?

I am flirting with the limits of my knowledge and I do feel the pain. Pretty sure, I will have to learn a lot, but if you would be so kind as to help me climb the first steps...


回答1:


You don't need to use reflection to create delegates in F#. You can ditch the first part of your code altogether (your CsharpAction module).

As for the second chunk of code, try this:

open System
open System.Collections.Generic
open System.Threading.Tasks

let yymmdd1 (date : DateTime) = date.ToString "yy.MM.dd"
let printSuccess () = printfn "Success %s" (yymmdd1 DateTime.Now)

let server =
    let actionTask = Action printSuccess
    let properties = Dictionary (dict ["fooKey", obj ()])
    OwinServerFactory.Create((fun props -> new Task (actionTask)), properties)


来源:https://stackoverflow.com/questions/18802085/create-an-action-in-f-in-order-to-use-a-c-sharp-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!