2

由于我有大量的IDisposables 需要处理一段时间,因此我设置了一个一次性物品列表和一个传递函数,以将项目添加到其中作为副作用:

let mutable disposables = []
let (~-) (x:'a) = disposables <- x :: disposables; x

这样我就有希望做到这一点:

let thing1 = -new Form()
let thing2 = -new Control()

for i in disposables do i.Dispose()

问题是 F# 自动限制'aIDisposable,并带有警告消息:

这种构造导致代码不像类型注释所指示的那样通用。类型变量“a”已被限制为“IDisposable”类型。

那么返回类型operator ~-就变成了IDisposable,破坏了函数的便利性。

有没有办法阻止 F# 创建这个约束?

4

2 回答 2

2

知道了!

答案是当我在函数中使用它时向上x转换IDisposable,而不是在函数的类型签名中:

let mutable disposables = []
let (~-) x = disposables <- (x :> IDisposable) :: disposables; x
于 2012-07-28T01:13:33.560 回答
1

您没有就您的代码征求一般性建议,但我觉得有必要指出一些奇怪的地方。

首先,您几乎不需要调用Dispose(). use是管理资源的标准方式。你可能应该这样做:

use thing1 = new Form()
use thing2 = new Control()

其次,为什么要将不可变的数据结构分配给mutable变量?如果您确信需要手动跟踪资源,请使用

let disposables = ResizeArray<IDisposable>()

最后,在定义一个在其自身范围之外改变变量的运算符之前,您应该仔细考虑。这对于操作员来说是不寻常的行为(除非操作员的范围非常狭窄)。

于 2012-07-28T03:38:28.183 回答