[英]Defining static classes in F#
是否可以在 F# 中定义包含可重载成员的静态类? let
模块绑定不能被重载,即使它们被编译成静态类中的静态静态成员。
type
可以包含静态成员,但我不知道类型本身是否可以设为静态。
我目前的解决方案是用私有构造函数定义一个type
,然后使用它。 我想知道是否有一种方法可以根据需要定义静态类型。
正如 Robert Jeppeson 指出的那样,C# 中的“静态类”只是创建一个不能实例化或继承的类的简写,并且只有静态成员。 以下是在 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
和私有构造函数都会阻止您创建类的实例,但是,这就是 C# 静态类所做的 - 它们被编译为具有私有构造函数的抽象类。 Sealed
属性阻止您从此类继承。
如果您像在 C# 中那样添加实例方法,此技术不会导致编译器错误,但从调用者的角度来看,没有区别。
[<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#")
仍然可以定义实例方法,但是当没有可用的构造函数时,您无法实例化该类。
2021 年 1 月编辑:请参阅 Abel 的评论和相关问题。 迄今为止,乔尔·穆勒 (Joel Mueller) 的回答似乎是最好的建议,但未来可能会发生变化。
我不确定是否有静态类之类的东西。 我相信,C# 类级别上的“静态”是在 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
所以,你现在正在做的就是做这件事的方法。
在 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-bounds:
let inline ( |+| ) m1 m2 = (Overloads $ m1) m2
当您能够使用此方法重载 let-bounds 时,您应该创建一个包装模块来保存这些函数并将您的类型标记为private
。
我认为这里的问题是试图将 F# 变成 C#。 如果问题不能以非命令式方式解决,请使用 C# 或编写一个面向对象的库并在 F# 中使用它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.