В F #, как я могу создать выражение с типом Func <obj>?

Я работаю с api, для которого требуется значение типа Func. (В частности, я пытаюсь вызвать ModelMetadataProviders.Current.GetMetadataForType().

Как я могу построить это значение в F #?

Ответ 1

При вызове метода, который принимает любой делегат из Func, вам не нужно явно создавать делегат, потому что F # неявно преобразует лямбда-выражения в тип делегирования (в вызовах членов). Я думаю, что просто вызов метода с лямбда-функцией должен работать (если это не так, вы можете поделиться сообщением об ошибке?)

Вот простой пример, демонстрирующий это:

type Foo() = 
  member x.Bar(a:System.Func<obj>) = a.Invoke()

let f = Foo()
let rnd = f.Bar(fun () -> new Random() :> obj)

В вашем случае, я полагаю, что-то вроде этого должно работать:

m.GetMetadataForType((fun () -> <expression> :> obj), modelType)

Обратите внимание, что вам нужен явный upcast (expr :> obj), чтобы убедиться, что функция лямбда возвращает правильный тип (obj). Если вы хотите присвоить лямбда-функцию локальному значению с помощью let, то это не сработает, потому что неявное преобразование работает только тогда, когда оно передается как аргумент напрямую. Однако в этом случае код становится немного приятнее.

Ответ 2

Обычно вы можете передать любой () -> obj, и он будет автоматически преобразован в Func<obj>. Возможно, вам понадобится обернуть fun с помощью Func<obj>:

> let d : Func<obj> = Func<obj>(fun () -> box "hello");;

val d : Func<obj>

Ответ 3

let f = new System.Func<obj>(fun() -> printfn "ok"; new obj())