Расширение индексатора для существующего класса - PullRequest
2 голосов
/ 08 марта 2011

Предположим, у меня есть тип А с реализованным индексатором, например Тип А - это библиотека. Теперь я хочу расширить его индексатор, например, здесь я хочу добавить число с плавающей точкой в ​​индексатор.

Я разработал следующий код:

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 ]

5 голосов
/ 08 марта 2011

Это ведет себя по-разному, когда расширение типа определено в отдельной сборке (или отдельном модуле) и когда оно находится в том же модуле, что и определение типа.

  • Когда оба находятся в одном модуле, F # компилирует их в один класс и Item становится стандартным перегруженным индексатором - в этом случае ваш код работает как положено (и именно так вы и написали здесь ).

  • Когда они находятся в отдельных модулях, F # компилирует индексатор как элемент расширения. В этом случае я получаю сообщение об ошибке, которое вы описали.

Возможно добавление новых перегрузок с использованием элементов расширения (например, нового метода). Насколько я вижу, спецификация не говорит, что это не должно работать для индексаторов, поэтому я думаю, что это ошибка (вы можете сообщить об этом fsbugs в microsoft точка com ?)

2 голосов
/ 08 марта 2011

Я только что попробовал это в 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'

0 голосов
/ 31 марта 2014

Описание ошибки говорит об этом довольно четко - ожидается int, учитывая float, поэтому проблема 1.0, если вы замените ее на 1, она должна работать.

1 - int

1.0is float

1.0f is float32, aka double в некоторых языках

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...