如何定义泛型函数及其 return 参数

How to define a generic function and its return parameter

我正在努力解决一个关于泛型的看似微不足道的问题。

我有这些方法

 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>

这一切都很好 - 除了 return 类型。我绝对需要 RowDefinitonCollection 而不是 DefinitionCollection<RowDefinition>

有人知道如何完成这个吗?

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

# 通过一个简单的示例为我解决了这个问题,尽管您可能需要注释 toRowDefinitions/toColsDefinitions 来确定确切的 return 类型嗯

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

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

其中 ICollection<_> 是来自 System.Collections.Generic 的那个,当然,如果您需要具体类型,您可以使用 DefinitionCollection<_>

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

还有一种类型安全性较低的方法,使 toTypedCollection 内联并添加一个静态成员约束,r 需要一个 Add 方法;但是有了它,它可以在 any 类型上使用 Add 方法工作,这通常不是一个好主意。