如何定义泛型函数及其返回参数

时间:2015-04-07 10:54:57

标签: generics f#

我正在努力解决有关仿制药的一个看似微不足道的问题。

我有这些方法

 let toTypedCollection r l = 
     l |> List.iter (fun x -> r.Add(x)
     r
 let toRowDefinitions = toTypedCollection (new RowDefinitionCollection())
 let toColsDefinitions = toTypedCollection (new ColumnDefinitionCollection())

,其中

public sealed class ColumnDefinitionCollection : DefinitionCollection<ColumnDefinition>

public sealed class RowDefinitionCollection : DefinitionCollection<RowDefinition>

现在我收到编译器错误,告诉我r.Add需要使用类型信息进行扩充。所以我这样做

let toTypedCollection (r:DefinitionCollection<_>) l = ...

现在问题是toRowDefinitions的结果签名看起来像

DefinitionCollection<RowDefiniton> -> list RowDefinition -> DefinitionCollection<RowDefinition>

这一切都很好 - 除了返回类型。我绝对需要RowDefinitonCollection代替DefinitionCollection<RowDefinition>

有人知道如何做到这一点吗?

2 个答案:

答案 0 :(得分:2)

试试let toTypedCollection<'T> (r: #DefinitionCollection<'T>) l = ...

#在一个简单的示例中解决了我的问题,但您可能需要注释toRowDefinitions / toColsDefinitions以确定确切的返回类型。

答案 1 :(得分:1)

我认为你正在寻找这样的东西:

let toTypedCollection (r : 'T when 'T :> ICollection<_>) l = 
    l |> List.iter (fun x -> r.Add(x))
    r

其中ICollection<_>System.Collections.Generic中的DefinitionCollection<_>,但当然,如果您需要具体类型,则可以使用'T

scrwtp's answer显示较短的符号来实现类似的类型注释而不命名'T when 'T :> ICollection<_>:您还可以编写#ICollection<_>而不是'T。在这种情况下,toTypedCollection未在其他地方使用,因此这种表示法更短。

使r内联并添加Add需要Add方法的静态成员约束的类型安全性较低;但有了它,它将适用于任何带有{{1}}方法的类型,这通常不是一个好主意。