扩展现有类的Indexer

时间:2011-03-08 10:22:29

标签: f#

假设我有一个带有索引器的类型A,例如A型是一个图书馆。现在我想扩展它的索引器,例如在这里,我想在索引器中添加浮点数。

我制定了以下代码:

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]
a.[1] <- 10

a.[1.0]

对于最后一行,我得到:

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

在F#中扩展索引器是否可行?谢谢!

3 个答案:

答案 0 :(得分:5)

当在单独的程序集(或单独的模块)中定义类型扩展并且它与类型定义位于同一模块中时,这种行为会有所不同。

  • 当两者都在同一个模块中时,F#将它们编译成一个类,Item成为标准的重载索引器 - 在这种情况下,你的代码按预期工作(这就是你实际写的方式它在这里)。

  • 当它们位于单独的模块中时,F#将索引器编译为扩展成员。在这种情况下,我收到您描述的错误消息。

使用扩展成员(例如新方法)添加新的重载是可能的。我可以看到,specificaton并没有说这对索引器不起作用,所以我认为这是一个错误(你可以在 fsbugs 报告它吗? microsoft dot com ?)

答案 1 :(得分:2)

我刚刚在FSI尝试了这个,它似乎有效。 你用的是什么编译器? 这就是我向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]

这会打印'10'

答案 2 :(得分:0)

错误描述非常清楚 - 期望int,给定float,所以问题是1.0,如果你用1替换它,它应该工作。

1是int

1.0是浮动

1.0f是float32,在某些语言中又称为双倍