Extending the Indexer for an existing class

半城伤御伤魂 提交于 2019-12-08 02:20:31

问题


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(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!


回答1:


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?)




回答2:


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'




回答3:


The error description says it pretty clearly - expected int, given float, so the problem is 1.0, if you replace that with 1, it should work.

1 is int

1.0 is float

1.0f is float32, aka double in some languages



来源:https://stackoverflow.com/questions/5231145/extending-the-indexer-for-an-existing-class

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!