繁体   English   中英

在 F# 中定义静态类

[英]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# 中那样添加实例方法,此技术不会导致编译器错误,但从调用者的角度来看,没有区别。

这在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#")

仍然可以定义实例方法,但是当没有可用的构造函数时,您无法实例化该类。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM