2013-07-30 3 views
3

У меня есть метод расширенияКак включить этот метод расширения в свойство расширения?

type System.Int32 with 
    member this.Thousand() = this * 1000 

но это требует от меня, чтобы написать, как этот

(5).Thousand() 

Я хотел бы, чтобы избавиться от оба скобки, начиная с, что делает его свойство вместо метода (ради обучения), как я могу сделать это свойством?

ответ

7

Ответ Джона является один из способов сделать это, но свойство только для чтения, есть также более краткий способ, чтобы написать это:

type System.Int32 with 
    member this.Thousand = this * 1000 

Кроме того, в зависимости от ваших предпочтений , вам может показаться более приятным написать 5 .Thousand (обратите внимание на дополнительное пространство), чем (5).Thousand (но вы не сможете сделать только 5.Thousand или даже 5.ToString()).

+0

+1 - Я не знал, что пространство в '5.Thousand' сделает для действительного синтаксиса. –

3

Я не знаю F # (! Постыдным), но на основе this blog post, я бы ожидать:

type System.Int32 with 
    member this.Thousand 
     with get() = this * 1000 

Я подозреваемый что не освободит вас от первого набора скобок (в противном случае F # may попытайтесь разобрать все это как литерал), но он должен помочь вам со вторым.

Лично я бы не использовал этот тип для расширения «производства», но он полезен для тестового кода, где вы работаете с множеством значений.

В частности, я нашел аккуратным метод расширения по датам, например. 19.June(1976) как очень простой, легко читаемый способ создания тестовых данных. Но не для производства кода :)

+1

Я тоже грустно, что он не позволит мне написать расширение на все типы int сразу – Maslow

+0

Не для производственного кода из-за накладных расходов (производительности)? – Maslow

+1

@Maslow: Нет, потому что это редко полезно в моем опыте - и использование его на непостоянной будет выглядеть странно (например, «x.Thousand»). Я бы предпочел просто показать умножение, я думаю. Но для создания тестовых данных - yay! –

2

Это не красиво, но если вы действительно хотите функцию, которая будет работать для любого числового типа, вы можете сделать это:

let inline thousand n = 
    let one = LanguagePrimitives.GenericOne 
    let thousand = 
    let rec loop n i = 
     if i < 1000 then loop (n + one) (i + 1) 
     else n 
    loop one 1 
    n * thousand 

5.0 |> thousand 
5 |> thousand 
5I |> thousand 
+2

Yikes - вы можете уйти с меньшим количеством арифметических операций, чем это ... Что-то вроде: 'let one = ...; пусть два = один + один; пусть десять = два * (два + два + один); десять * десять * десять'. – kvb

+1

Да, это может быть намного эффективнее. В идеале вы должны вычислить тысячу раз и сохранить его как члена модуля. Тогда механизм его вычисления становится несущественным. – Daniel

+1

Несомненно, это тоже возможно: 'type ThousandCache <^ a, когда^a: ...> = static let thousand = ... static member inline Thousand = тыс. – kvb

Смежные вопросы