在 c# dll 中,我有一个方法,它采用 func 参数:public static AttrDiffRule Create<T>(string a_attr, string b_attr, Func<IAttrProxy,IAttrProxy,T,bool> parametricRule, T ruleParam, string desc = null)以及一些预定义的默认方法:public static bool NumberEqualsWithTolerance(IAttrProxy a, IAttrProxy b, double tolerance)现在在 C# 中使用它时,我可以编写以下内容并且它可以工作:var tmp = DefaultRules.Create("fds", "fds", DefaultRules.NumberEqualsWithTolerance, 10.0);但是,在 F# 中:let attrRule = DefaultRules.Create("fd","fdsa", DefaultRules.NumberEqualsWithTolerance, 89.)给出语法错误:“错误 FS0002 此函数需要太多参数,或者在不需要函数的上下文中使用”将 C# 静态方法传递给在 F# 中需要 Func 的参数的正确方法是什么?重要的是实际传入函数,而不是 lambda 包装器,因为 Create 方法的工作是使用参数函数的 MethodInfo,它被 lambda 包装器的 MethodInfo 隐藏。传入的函数没有重载,也尝试在适当的地方指定类型,如(DefaultRules.NumberEqualsWithTolerance : Func<IAttrProxy,IAttrProxy,float,bool>) 最佳答案 这是 F# 代表您非常周到的一个案例 - 通过帮助您编写更惯用的 F#。在 .NET 中,您实际上并未传入函数,就好像它是成员引用一样,而是传入了 Func<> 类型的委托(delegate)对象。委托(delegate)对象的构造在 C# 具有必要的类型信息时隐式完成。如果我们将其重构为实际的委托(delegate)类型,我们可以更清楚地看到这一点:public delegate bool ParametricRule<T>(IAttrProxy a, IAttrProxy b, T value);public static AttrDiffRule Create<T>(string a_attr, string b_attr, ParametricRule<T> parametricRule, T ruleParam, string desc = null){ return default;}如果你尝试在 F# 中构造一个 ParametricRule,你会看到它的类型是:ParametricRule(IAttrProxy -> IAttrProxy -> 'a -> bool)基本原理是这样您就可以使用常规 F# 函数,而不是一些非 F#ish 元组输入函数。这就是为什么它不适用于您的情况。因为您正试图将 C# 中的元组版本直接扔回去。因此,如果您将 C# 实现重构为:protected static bool NumberEqualsWithToleranceImpl(IAttrProxy a, IAttrProxy b, float tolerance){ return default;}public static ParametricRule<float> NumberEqualsWithTolerance => NumberEqualsWithToleranceImpl;您会看到它的工作方式与您期望的一样,无论是在 F# 还是 C# 中。let attrRule = DefaultRules.Create("fd","fdsa", DefaultRules.NumberEqualsWithTolerance, 89.0f) //compiles, yay!关于F# 将 C# 方法传递到另一个需要 Func<> 参数的 C# 方法中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/60376320/
10-12 22:08