F#代码引用中运行时构造GetArray调用获取数组元素的问题
问题原因
你遇到的类型不匹配问题是因为没有正确获取并特化GetArray泛型方法:
- 你通过
GetArray.GetType().GetMethods().[0]拿到的是泛型函数值对应的运行时Invoke方法,不是IntrinsicFunctions类中定义的静态GetArray泛型方法定义 - 你使用的是未绑定类型参数的开放泛型方法,没有针对
float数组场景做特化,调用时自然会出现类型校验失败
解决方案
你需要先获取GetArray的泛型方法定义,再根据你的数组元素类型构造封闭泛型方法后再构建表达式,完整实现代码如下:
open System open System.Reflection open FSharp.Quotations // 定义输入数组参数 let arrVar = Var("arr", typeof<float array>, false) // 从IntrinsicFunctions类获取GetArray泛型方法的原始定义 let getArrayGenericDef = typeof<FSharp.Core.LanguagePrimitives.IntrinsicFunctions> .GetMethod("GetArray", BindingFlags.Public ||| BindingFlags.Static) // 针对float类型构造特化的封闭泛型方法 let getArrayForFloat = getArrayGenericDef.MakeGenericMethod(typeof<float>) // 构造数组访问表达式 let arrAccessExpr = Expr.Call(getArrayForFloat, [Expr.Var(arrVar); Expr.Value(0)]) // 如果需要实现你示例中的 2.0 * arr.[0] 完整lambda,补充乘法逻辑即可 let multiplyMethod = typeof<float>.GetMethod("op_Multiply", [| typeof<float>; typeof<float> |]) let fullLambdaExpr = Expr.Lambda( arrVar, Expr.Call(multiplyMethod, [Expr.Value(2.0); arrAccessExpr]) )
构造完成后你可以打印fullLambdaExpr对比代码引用的结构,和你示例中<@ fun (arr: float array) -> 2.0 * arr.[0] @>的输出完全一致。
内容的提问来源于stack exchange,提问作者RMills330
相关产品推荐
相关产品推荐

