F#静态成员约束与IDisposable相结合

时间:2020-09-01 16:57:57

标签: .net compiler-errors f# type-constraints

我想实现一个通用的F#类,该类的类型参数肯定提供了一个称为“ TryParse”的静态方法。除此之外,我希望我的课程在不再需要后得到正确处理。我提出了以下实现:

.input {
  position: relative;
  width: fit-content;
  display: flex;
  justify-content: center;
  align-items: center;
}
img {
  position: absolute;
  right: 5px;
  width: 10px;
}

问题是:在两个成员(“开始”和“处置”)上,我都遇到以下错误:

type Listener<'a when ^a : (static member TryParse : string -> ^a option)>() =
   // construct the object here
   let input : string = "" // get input
   let res = (^a : (static member TryParse : string -> ^a option) input)

   member this.Start() =
       // ...
       ()

   interface IDisposable with
      member this.Dispose() =
         // do cleanup
         ()

我可以通过用“ inline”装饰它来在Start()成员上修复它,但是我无法对接口定义做同样的事情。

是否既可以强制执行我的通用类型以实现静态方法,又可以定义Disposable类?

1 个答案:

答案 0 :(得分:6)

如注释中所述,类不能具有静态解析的类型参数。如果您想做这样的事情,一个很好的技巧是拥有一个内联方法,该方法具有约束并捕获以后将需要在接口中或作为一等函数使用的操作。

在您的情况下,您可以更改类以将tryParse : string -> 'a option作为参数,然后使用静态方法,该方法将自动为支持它的类型捕获它:

type Listener<'a>(tryParse : string -> 'a option) =
   let input : string = "" 
   let res = tryParse input

   member this.Start() = ()

   interface System.IDisposable with
      member this.Dispose() = ()

具有静态内联成员的非泛型类型将是:

type Listener = 
  static member inline Create< ^b 
      when ^b : (static member TryParse : string -> ^b option)>() = 
    new Listener< ^b >(fun input -> 
      (^b : (static member TryParse : string -> ^b option) input))

假设您拥有类型Foo和适当的TryParse成员,则可以编写:

let l = Listener.Create<Foo>()
相关问题