[英]Is there a safe way of converting a Collection to a sequence in F#?
[英]converting an enum to a list or sequence or generic collection type in F#
我有一个类型是Dictionary<string,Node<'a>>*Edge<'a> list
或ConcurrentDictionary<string,Node<'a>>*Edge<'a> list
。 我正在尝试创建一个get_nodes
函数,但是当我从Dictionary
和ConcurrentDictionary
调用.Values
时,这些函数返回不同的类型!
所以我需要以某种方式将这两种类型转换为相同的类型,以便 F# 编译...
Dictionary.Values
给出的类型是Dictionary'2.ValueCollection<string,Node<'a>>
而ConcurrentDictionary
产生的类型是ICollection<Node<'a>>
。
我发现这两种类型都有一个“GetEnumerator()”函数。 我需要做的是以某种方式将枚举器转换为 seq 或列表等。
这是我的代码:
static member get_nodes (g:Graph<'a>) =
match g with
| Dictionary_Graph(nd,el) -> let n = nd.Values
let enum = n.GetEnumerator()
| ConcurrentDictionary_Graph(nd,el) -> let n = nd.Values
let enum = n.GetEnumerator()
如何从枚举变量中提取数据?
您可能已经习惯了 C#,它会自动将 ValueCollection 向上转换为 ICollection(ValueCollection 实现)。 F# 不会这样做,因此您必须手动将 Dictionary.Values 的结果转换为 ICollection。
let n = nd.Values :> ICollection<Node<'a>>
完整方法看起来像这样:
static member get_nodes (g:Graph<'a>) =
match g with
| Dictionary_Graph(nd,el) ->
nd.Values :> ICollection<Node<'a>>
| ConcurrentDictionary_Graph(nd,el) ->
nd.Values
据我了解,由于自动类型推理引擎的工作方式,F# 不会自动向上转换。 当您习惯了 C# 时,这很烦人,但为了获得自动类型推断而付出的代价是值得的。 还要考虑到,在 C# 中,您必须在方法的前面指定返回类型,这使得 C# 可以轻松地为您进行转换。 F# 引擎根据您实际返回的内容推断返回类型,因此最安全的做法是不要假设您希望它如何转换。
不是普遍共识,但我的意见是:我希望他们会为特定情况添加返回值的自动向上转换(例如提前声明输出类型或使分支符合上述要求),但现在这是一个小问题。
更新(来自评论中的问题)
ICollection<T>
现在应该可以直接用作序列,因为它实现了IEnumerable<T>
。 在这种情况下,自动向上转换实际上确实有效。 :)
myGraph
|> Graph.get_nodes
|> Seq.iter (fun x -> printfn "%A" x)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.