【问题标题】:Func<T, TResult> property in F#F# 中的 Func<T, TResult> 属性
【发布时间】:2013-12-02 09:59:18
【问题描述】:

我目前正在与 F# 中的 C# 代码进行互操作。

是否可以在 F# 中定义一个在 C# 中如下所示的属性?

private Func<PropertyInfo, bool> OnIsSatisfiedByProperty { get; set; }

(在 F# 中,它不必是 Func&lt;T, TResult&gt;,而是等价的。)

【问题讨论】:

  • 还有更多信息吗?即这真的是 protectedpublic 吗?您是否在 F# 中声明将在 C# 中使用的接口?你将如何初始化它?有一个实际的 getter 或 setter 方法重要吗?你关心有保护条款的二传手吗?在没有进一步上下文的情况下,我的默认答案是let private mutable OnIsSatisfiedByProperty : (PropertyInfo -&gt; bool) option = None。然后您可以使用Option.iter et.al 删除空检查。或者,您可以将其作为主要 ctor arg 进行工作:type X( ?OnIsSatisfiedByProperty) = ... 如果可变性没有价值
  • @RubenBartelink 它可以被声明为内部的,但这在我的场景中并不重要。它实际上是一个测试类型。可以使用构造函数注入来提供该值,但对于此类测试类型,我习惯性地使用对象初始化器来提供。
  • 所以,我们可以假设您在 F# 中声明测试类型,然后需要它可以从 C# 初始化,因此这不是“可能”internal 的问题 - 你需要它public/internal 而不是private?如果是这样,静态类型就变得非常重要; @John Palmer 的回答(和我的评论)创建了一个 FSharpFunc&lt;PropertyInfo,bool&gt;,因此他的扭曲必须重新初始化。
  • 测试类型是在 F# 中定义的,它将在 F# 中使用。设计是 C#-ish(我也有一个 C# 中的工作示例,因此具有初始互操作性) - 现在我首先遵循 OO 设计以查看测试通过,然后,我想,我会慢慢转向更多的 FP范式。
  • 很公平 - 最终,如果您需要/想要一个公共设置器,那么 val 是要走的路。但我希望转向 type test( onIsSatisfiedByProperty? ) = 结构,以便能够依靠 Option.* - 但这取决于您实际互操作要求的确切性质

标签: c# f#


【解决方案1】:

如果您需要与 C# 中的类型进行互操作,则您希望它是 Func&lt;T&gt;,而不是 FSharpFunc,后者具有额外的元数据,例如非 null 规定[就像我之前的 cmets 和 @John帕尔默的答案最终是]。因此,您可以使用对象初始化器初始化的最短的类似实际等效项是:

type MyType()=
    member val public OnIsSatisfiedByProperty : Func<PropertyInfo,bool> = null with get,set

或者你可以走以下路线:

type MyType()=
    [<DefaultValue()>]val mutable OnIsSatisfiedByProperty : Func<System.Reflection.PropertyInfo,bool> 

但是在这种情况下,我的快速混乱让我需要实现显式的 set/get 方法。

(顺便说一句,我知道这个答案只是因为碰巧几分钟后,fixture.Inject( fun () -&gt; !value) 的工作方式与fixture.Inject&lt;Func&lt;MyValue&gt;&gt;( fun () -&gt; !value) 不同!)

【讨论】:

  • 鉴于以下codethis answer 似乎有效。我尝试应用您提供的 sn-ps,但代码没有编译...:/
  • @NikosBaxevanis 稍后再看。不能说我对它们进行了测试或 ILSpyed,但是没有波浪线,FSI 处理了它们.... :)
  • @NikosBaxevanis 如果你说的是不应用Func,你需要一个.Invoke 最后......但我想如果它以另一种方式工作,有def优点(因此我对此 +1)。我想cinst ILSpy 应该会告诉你你需要知道的一切。另见FuncConvert and associated stuff
  • 哦,我明白了:)没问题。非常感谢您的帮助。我将this answer 设置为已接受,因为它与我现有的要点开箱即用。
  • @NikosBaxevanis 是的,这很公平 - 如果您不需要将内容作为 Func 公开,则没有必要。很好,你已经解决了......
【解决方案2】:

我认为相当于

type test() = 
        member val private OnIsSatisfiedByProperty:PropertyInfo -> bool = (fun _ -> true) with get,set;;

【讨论】:

  • 非常感谢您的帮助。这似乎开箱即用:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多