Подтвердить что ты не робот

Определение статических классов в F #

Можно ли определить статический класс, содержащий перегружаемые члены в F #? let привязки модулей нельзя перегружать, даже если они скомпилированы в статические статические элементы в статических классах.

type declerations могут содержать статические члены, но я не знаю, может ли сам тип быть статическим.

Мое текущее решение - определить type с помощью частного конструктора и просто использовать его. Мне интересно, есть ли способ определить статический тип, как я хочу.

4b9b3361

Ответ 1

Как отметил Роберт Джеппсон, "статический класс" на С# является лишь короткой рукой для создания класса, который не может быть создан или унаследован, и имеет только статические члены. Вот как вы можете выполнить именно это в F #:

[<AbstractClass; Sealed>]
type MyStaticClass private () =
    static member SomeStaticMethod(a, b, c) =
       (a + b + c)

    static member SomeStaticMethod(a, b, c, d) =
       (a + b + c + d)

Это может быть немного излишним, поскольку как AbstractClass, так и частный конструктор помешают вам создать экземпляр класса, однако это то, что делают статические классы С# - они скомпилированы в абстрактный класс с частным конструктором. Атрибут Sealed не позволяет наследовать этот класс.

Этот метод не вызовет ошибку компилятора, если вы добавите методы экземпляра, как это было бы на С#, но с точки зрения вызывающего нет никакой разницы.

Ответ 2

Я не уверен, что есть такая вещь, как статический класс. "Статический" на уровне класса в С# был представлен в 2.0, я считаю, в основном как удобство (избегайте частных конструкторов и проверки времени компиляции, чтобы не присутствовали члены экземпляра). Вы не можете изучить тип и сделать вывод, что он статичен: http://msdn.microsoft.com/en-us/library/system.reflection.typeinfo.aspx

Обновление: MSDN объявляет, что статический класс - это класс, который запечатан и имеет только статические члены: http://msdn.microsoft.com/en-us/library/79b3xss3(v=vs.80).aspx

Итак, что вы делаете в данный момент, это способ сделать это.

Ответ 3

В F # нет возможности для определения статических типов.

Первым альтернативом является определение модуля, но он не имеет возможности перегружать функции (это то, что вам нужно). Второй вариант - объявить нормальный тип со статическими членами.

Что касается второго подхода, это именно то, что принятый ответ для вашего старого описанного вопроса. Я реорганизую код, чтобы объяснить это проще. Во-первых, определены фиктивные однократные раздельные объединения:

type Overloads = Overloads

Во-вторых, вы используете тот факт, что статические члены могут быть перегружены:

type Overloads with
    static member ($) (Overloads, m1: #IMeasurable) = fun (m2: #IMeasurable) -> m1.Measure + m2.Measure 
    static member ($) (Overloads, m1: int) = fun (m2: #IMeasurable) -> m1 + m2.Measure

В-третьих, вы распространяете ограничения этих перегруженных методов на ограничения, используя ключевое слово inline:

let inline ( |+| ) m1 m2 = (Overloads $ m1) m2

Когда вы можете перегрузить let-bounds с помощью этого метода, вы должны создать модуль-оболочку для хранения этих функций и пометить свой тип private.

Ответ 4

Это объясняется в Принципы проектирования компонентов F #.

[<AbstractClass; Sealed>]
type Demo =
    static member World = "World"
    static member Hello() = Demo.Hello(Demo.World)
    static member Hello(name: string) = sprintf "Hello %s!" name

let s1 = Demo.Hello()
let s2 = Demo.Hello("F#")

По-прежнему можно определить методы экземпляра, но вы не можете создавать экземпляр класса, когда нет конструктора.

Ответ 5

Я думаю, что проблема здесь заключается в том, чтобы сделать F # на С#. Если проблема не может быть решена не обязательно, используйте С# или напишите объектно-ориентированную библиотеку и используйте ее в F #.