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"

このライブラリを使用するコードでは、同じ名前のメソッドを 1 つ追加します (したがって、 です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ますが、ここでは別の型シグネチャを使用します。新しいメソッドが拡張されないのはなぜですか?

4

3 に答える 3

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

この問題は、拡張メソッドが次のように実装されていることが原因であると思います (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 に答える