5

我有一个已经实现.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# 文档说:

扩展方法不能是虚拟或抽象方法。它们可以重载其他同名方法,但在调用不明确的情况下,编译器会优先使用非扩展方法。

这意味着我不能.ToString/.GetHashCode使用相同的类型签名进行扩展,但在这里我使用了不同的类型签名。为什么不能扩展新方法?

4

3 回答 3

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"
于 2012-11-16T11:54:22.993 回答
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作为返回类型,但这并不是问题所在。

于 2012-12-27T17:32:55.623 回答
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
于 2017-08-20T05:20:19.883 回答