Lambda 将F#func转换为表达式<;Func<&燃气轮机&燃气轮机;

Lambda 将F#func转换为表达式<;Func<&燃气轮机&燃气轮机;,lambda,casting,f#,c#-to-f#,Lambda,Casting,F#,C# To F#,我有一个具有以下签名的函数的模块: modulesomething= 让someFunc func=/('TType->'TField)->'TValue ... 在该函数中,我从某个外部库调用一个函数,该库有一个具有以下签名(C#)的方法: class-SomeClass { 公共返回类型SomeMethod(func:Expression){…} } 当我试图传递一个'TType->'TField函数时,我得到一个错误,它不能转换为表达式。我在StackOverflow上发现了以下问题:

我有一个具有以下签名的函数的模块:

modulesomething=
让someFunc func=/('TType->'TField)->'TValue
...
在该函数中,我从某个外部库调用一个函数,该库有一个具有以下签名(C#)的方法:

class-SomeClass
{
公共返回类型SomeMethod(func:Expression){…}
}
当我试图传递一个
'TType->'TField
函数时,我得到一个错误,它不能转换为
表达式
。我在StackOverflow上发现了以下问题:

但这并不能解决我的问题(第一个答案不起作用,第二个答案起作用,但我必须更改我函数的签名)

对于第二个答案,我必须将我的函数签名更改为以下内容:

modulesomething=
设someFunc func=//表达式)->'TValue
...
为我的模块的“客户端”添加可见的附加类,如下所示:

type ExpressionHelper()=
静态成员AsExpression(e:Expression)=e
因此,最后的调用如下所示:

let=Something.someFunc(fun(o:SomeType)->o.someField)
看起来是这样的:

let=Something.someFunc(ExpressionHelper.AsExpression(fun(o:SomeType)->o.SomeField))

我不想强制模块的
用户
显式地将F#函数转换为
表达式
。我想在我的模块中实现这一点,有什么方法可以实现吗?

如果您有一个类型为
'T1->'T2
的值,那么您无法将其转换为类型为
表达式的值。这是不可能的,因为前者是一个编译函数(引用某个对象及其方法的委托),而后者是原始源代码的表示

因此,您需要使用
Expression
作为参数的类型来实现这一点(或者
Expr
,如果要使用引号,这是F#等价物)

但是,在F#中,编译器会自动将使用lambda函数语法创建的值
fun x->..
转换为
Expression
类型的值。它不会对let绑定函数的参数执行此操作,但会对静态方法的参数执行此操作。这意味着您可以使用:

open System
open System.Linq.Expressions

type A = 
  static member foo (f:Expression<Func<int, int>>) = 
    f.ToString()

A.foo (fun n -> n + 1)
开放系统
开放系统.Linq.Expressions
A型=
静态成员foo(f:Expression)=
f、 ToString()
A.foo(乐趣n->n+1)

这正是我所担心的:(.我一开始就按照你的建议做了(见我问题的底部)。但是我对这个解决方案不太满意。不过,谢谢你的回答,因为这不可能,我会接受它。@MNie是的,你的
ExpressionHelper.AsExpression
可以工作,因为它也是一个静态方法-但是你有没有理由不能让你的
成为某种东西。someFunc
也成为一个静态方法?即使
Something
是一个模块名,您应该能够定义一个具有相同名称的类型,并在其中使用静态方法(如果您使用
compileRepresentationFlags.ModuleSuffix
属性标记模块)