F#返回ICollection

Ric*_*odd 3 f# icollection

我正在使用C#创建的库.我一直在努力将一些代码移植到F#,但必须使用C#lib中的一些底层类型.

一段代码需要计算值列表并将其分配给类中的公共字段/属性.该字段是一个包含两个ICollection的C#类.

我的F#代码工作正常,需要返回F#Seq/List.

我尝试了以下代码片段,每个代码片段都会产生错误.

  • F#member的返回类型是一个名为recoveryList的类型,其类型为Recoveries list
  • 类中的公共字段,它本身包含两个ICollection对象

    this.field.Collection1 = recoveries
    
    Run Code Online (Sandbox Code Playgroud)

这给出了错误Expected具有类型ICollection但具有类型Recoveries列表

this.field.Collection1 = new ResizeArray<Recoveries>()
Run Code Online (Sandbox Code Playgroud)

给出错误预期类型ICollection但是ResizeArray

this.field.Collection1 = new System.Collections.Generic.List<Recoveries>()
Run Code Online (Sandbox Code Playgroud)

与上面相同的错误 - 预期的ICollection但类型是List

有任何想法吗?从C#的角度来看,这些操作似乎是有效的,而List/ResizeArray实现了ICollection所以...我很困惑如何分配值.

我可以更改底层C#库的类型,但这可能有其他含义.

谢谢

Jac*_* P. 7

F#不像C#那样进行隐式转换.因此,即使System.Collections.Generic.List<'T>实现了ICollection接口,也无法直接将某个ICollection-typed属性设置为实例System.Collections.Generic.List<'T>.

解决方法是容易做的-所有你需要做的就是添加一个显式上溯造型到ICollectionResizeArray<'T>System.Collections.Generic.List<'T>分配之前:

// Make sure to add an 'open' declaration for System.Collections.Generic
this.field.Collection1 = (recoveries :> ICollection)
Run Code Online (Sandbox Code Playgroud)

要么

this.field.Collection1 = (ResizeArray<Recoveries>() :> ICollection)
Run Code Online (Sandbox Code Playgroud)

  • 如果你感到懒惰,你可以使用`_`代替`ICollection`并让编译器推断它,或者使用`upcast`关键字代替. (4认同)