这是两个F#场景。我有一个抽象类:
type IAbstractObj =
abstract DoSomething : bool -> bool
我将接口实现为一个类型:
type ConcreteObj =
interface IAbstractObj with
member this.DoSomething bool = true
然后通过实例化在应用程序中使用它:
let foo = new ConcreteObj();
我使用let绑定绑定了该类型的实例,并将其用作“自由函数持有者”:
let ConcreteObj = {
new IAbstractObj with
member this.DoSomething bool = true
}
并按原样使用:
let foo = ConcreteObj
这些用法有何不同?在任何一种情况下,类型都不需要保留任何额外的运行时状态。
这对我的应用来说非常重要。我使用许多接口用于验证器和序列化器,它们不包含任何实例状态。有了我的C#背景,我习惯于拥有来创建一个继承接口的类的实例,即使它有一个无参数的构造函数,显然只是一个基本静态函数的持有者。 p>
答案 0 :(得分:3)
两者之间的主要区别在于对象表达式具有它实现的接口或抽象类的静态类型。然而,基于类的接口实现是显式的,并且需要强制转换才能访问接口成员。
对于简单的接口实现,对象表达式通常是比类更好的选择。
(FWIW,我认为您的性能问题无关紧要。)
答案 1 :(得分:3)
有一个比其中任何一个更惯用的选项。不要为每个选项创建新类型,只需创建一个记录类型,其中有两个成员即函数。你几乎在评论中自己定义了它:
type serializer<'a, 'b> =
{ Serialize : 'a -> 'a Option
Deserialize: 'b -> 'b Option}
let concrete = { Serialize = (fun (x)->Some(x)); Deserialize = (fun (x)->Some(x)) }
因此无论消费多少都需要serializer
。