如何在接口上添加 SRTP 约束?
How do I add SRTP constraints on an interface?
假设我想要一个带有成员 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
是否有任何原因导致您不能使用 .NET 运行时支持的普通接口约束?
type IEntity =
abstract Id : int
type IDatabase<'T when 'T :> IEntity> =
abstract member Save: 'T -> unit
使用 SRTP 和接口之间有两个主要区别:
.NET 运行时直接支持接口约束,F# 利用它,因此约束编译为 .NET 约束。使用 SRTP,必须在编译时满足约束,这会施加各种限制。
如果你引入一个接口,你必须能够修改所有你希望能够处理(实现接口)的类。使用 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
是否有任何原因导致您不能使用 .NET 运行时支持的普通接口约束?
type IEntity =
abstract Id : int
type IDatabase<'T when 'T :> IEntity> =
abstract member Save: 'T -> unit
使用 SRTP 和接口之间有两个主要区别:
.NET 运行时直接支持接口约束,F# 利用它,因此约束编译为 .NET 约束。使用 SRTP,必须在编译时满足约束,这会施加各种限制。
如果你引入一个接口,你必须能够修改所有你希望能够处理(实现接口)的类。使用 SRTP,您可以依靠“鸭子打字”和一个恰好已经存在的成员 类 您关心的。
如果第二个条件对你来说不是太严格(即你控制所有 类),那么接口是一个更简单的选择。