我有一个已经实施.Item
方法的.Net库,例如
namespace Library2
type A() =
member m.Item with get(a: string) = printfn "get a string"
member m.Item with get(a: int) = printfn "simple slice"
在使用此库的代码中,我想添加一个同名的额外方法(因此它是optional extensions
):
#r @"Library2.dll"
open Library2
type A with
member m.Item with get(a: bool) =
printfn "get a bool"
以下示例的最后一行无法编译:
let a = new A()
a.["good"]
a.[10]
a.[true]
F# doc说:
扩展方法不能是虚方法或抽象方法。他们能 重载其他同名的方法,但编译器给出 在呼吁模糊的情况下,优先考虑非扩展方法。
这意味着我无法使用相同的类型签名扩展.ToString/.GetHashCode
,但在这里我使用了不同的类型签名。为什么新方法无法扩展?
答案 0 :(得分:0)
我认为,问题是由事实扩展方法实现如下(C#):
public static class MyModule
{
public static void Item(this A a, bool b)
{
// whatever
}
}
编译器正在寻找.Item(...)
方法,在原始的Library2.A
类中找到它,并且无法搜索任何扩展方法。
请注意,如果所有 .Item(...)
重载都是扩展方法,那么一切正常:
module Library2 =
type A() =
member m.dummy = ()
open Library2
type A with
member m.Item with get(a: string) = printfn "get a string"
member m.Item with get(a: int) = printfn "simple slice"
member m.Item with get(a: bool) = printfn "get a bool"
答案 1 :(得分:0)
这似乎是编译器中的一个错误。扩展方法就在那里,当你放弃索引器带来的漂亮的语法糖时可以调用它,即这样可行:
库:
namespace TestLibrary
type A() =
member m.Item with get(a: string) = "string"
member m.Item with get(a: int) = "int"
主:
open TestLibrary
type A with
member m.Item with get(a: bool) = "bool"
[<EntryPoint>]
let main argv =
let a = new A()
printfn "%s" (a.get_Item "a")
printfn "%s" (a.get_Item 1)
printfn "%s" (a.get_Item true)
System.Console.ReadLine() |> ignore
0
我的第一个直觉是索引器不能将unit
作为返回类型,但这并不是问题所在。
答案 2 :(得分:0)
奇怪的是,我在LinqPad中创建了类似的东西,它按预期工作。
module ModuleA =
type A() =
member m.Item with get(a: string) = printfn "get a string"
member m.Item with get(a: int) = printfn "simple slice"
module ModuleB =
open ModuleA
type A with
member m.Item with get(a: bool) = printfn "get a bool"
open ModuleB
let a = new ModuleA.A()
a.["good"]
a.[10]
a.[true]
// get a string
// simple slice
// get a bool