开发者

Extending the Indexer for an existing class

开发者 https://www.devze.com 2023-02-15 06:50 出处:网络
Suppose I have type A with indexer implemented, e.g. type A is a library. Now I want to extend the indexer of it, e.g. here I want to add float number into the indexer.

Suppose I have type A with indexer implemented, e.g. type A is a library. Now I want to extend the indexer of it, e.g. here I want to add float number into the indexer.

I worked out the following code:

type A(a:int array) = 
  member this.Item
    with get(x) = a.[x]
    and  set(x) value = a.[x] <- value

type A with
    member m.Item with
     get(x:float) = m.[x |> int]
     and  set开发者_StackOverflow(x:float) v = m.[x |> int] <- v

But it seems not working:

let a = A([| 1;2;3 |])
a.[1]
a.[1] <- 10

a.[1.0]

For the last line, I get:

Script1.fsx(243,4): error FS0001: This expression was expected to have type
    int    
but here has type
    float    

Is extending indexer possible in F#? Thanks!


This behaves differently when the type extension is defined in a separate assembly (or separate module) and when it is in the same module as the type definition.

  • When both are in the same module, F# compiles them into a single class and Item becomes a standard overloaded indexer - In this case, your code works as expected (and this is how you actually wrote it here).

  • When they are in separate modules, F# compiles the indexer as an extension member. In this case, I get the error message you described.

Adding new overloads using extension members (e.g. new method) is possible. As far I can see, the specificaton doesn't say that this shouldn't work for indexers, so I think it is a bug (can you report it to fsbugs at microsoft dot com?)


I just tried this in FSI and it seems to work. What compiler are you using? This is what I fed to FSI:

type A(a:int array) = 
  member this.Item
    with get(x) = a.[x]
    and  set(x) value = a.[x] <- value

type A with
    member m.Item 
      with get(x:float) = m.[x |> int]
      and  set(x:float) v = m.[x |> int] <- v

let a = A([| 1;2;3 |])
a.[1] <- 10
printfn "%A" a.[1.2]

This prints '10'

0

精彩评论

暂无评论...
验证码 换一张
取 消