首页 > 解决方案 > 如何在接口上添加 SRTP 约束?

问题描述

假设我想要一个带有成员的接口,该成员Write接受一个泛型类型,该泛型类型被限制为具有一个Id: int字段。

这在 F# 中可能吗?我已经尝试过这个和它的变化,但总是得到The code is not sufficiently generic. The type variable... would escape its scope.错误。

其他类似的问题建议使用内联成员,但这在接口上是不可能的。

type IDatabase<'T when 'T : (member Id: int)> =
    abstract member Save: 'T -> unit

标签: f#

解决方案


有什么理由不能使用 .NET 运行时支持的普通接口约束?

type IEntity = 
  abstract Id : int

type IDatabase<'T when 'T :> IEntity> =
  abstract member Save: 'T -> unit

使用 SRTP 和接口之间有两个主要区别:

  • .NET 运行时直接支持接口约束,F# 利用了这一点,因此约束编译为 .NET 约束。使用 SRTP,必须在编译时满足约束,这会施加各种限制。

  • 如果您引入一个接口,您必须能够修改您希望能够处理的所有类(以实现该接口)。使用 SRTP,您可以依赖“duck typing”以及您关心的所有类中已经存在的成员。

如果第二个条件对您来说不是太严格(即您控制所有类),那么接口是一个更简单的选择。


推荐阅读