我试图使用带有F#代码的Rhino Mocks,以下代码存在问题:
let service = MockRepository.GenerateMock<IMyService>()
service.Stub(s => s.Name).Return("Service");
这并不奇怪,因为Stub不是IMyService接口的一部分,它是Rhino Mocks定义的C#扩展方法。
Slighltly修改代码的工作原理:
let service = MockRepository.GenerateMock<IMyService>()
RhinoMocksExtensions.Stub<IMyService, string>(service, fun s -> s.Name).Return("Service");
但是,在F#中定义扩展方法会很好,但是它将是一个参数化的通用扩展方法,它将采用元组。我正在尝试varios语法,但没有任何运气。我没有找到F#目前是否支持这些信息。如果有人知道,请告诉我。
答案 0 :(得分:4)
正如kvb所说,在F#2.0中是不可能的。在这种特殊情况下,我将包装Rhino.Mocks流畅的界面,使其在F#中更具惯用性,例如:
let mstub f target =
RhinoMocksExtensions.Stub(target, Function(f))
let mreturn value (options: IMethodOptions<'a>) =
options.Return value
let service = MockRepository.GenerateMock<IComparer>()
service |> mstub (fun s -> s.Compare(1,2)) |> mreturn 1 |> ignore
What's fluent in one language is not necessarily fluent in another.(对不起,但我觉得这很重要)
答案 1 :(得分:3)
如果我理解你的问题,答案是肯定的。 Section 8.12.1 of the spec(导入的C#扩展成员)包含以下文本:
制作C#定义的扩展成员 可用于环境中的F#代码 C#-authored程序集所在的位置 引用和公开声明 相应的命名空间在 影响。但是,有些局限性 申请,特别是
C#扩展成员“this” 参数是变量类型不是 在这里可以使用F#代码 F#的版本
C#扩展成员“this” 参数是数组类型不是 在这里可以使用F#代码 F#的版本
这解释了为什么C#中的某些扩展方法可以工作(例如System.Linq中的扩展方法),而您尝试使用的扩展方法则不会。
此外,原生F#扩展方法只能定义为放在实际的类型定义上。特别是,您不能在封闭的泛型类型(例如IEnumerable<string>
)上定义F#扩展方法,也不能在泛型类型变量上定义扩展方法。