Определение статических классов в F #
Можно ли определить статический класс, содержащий перегружаемые члены в F #? let
привязки модулей нельзя перегружать, даже если они скомпилированы в статические статические элементы в статических классах.
type
declerations могут содержать статические члены, но я не знаю, может ли сам тип быть статическим.
Мое текущее решение - определить type
с помощью частного конструктора и просто использовать его. Мне интересно, есть ли способ определить статический тип, как я хочу.
Ответы
Ответ 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 #.