gpt4 book ai didi

.net - 有没有一种安全的方法可以将 Collection 转换为 F# 中的序列?

转载 作者:行者123 更新时间:2023-12-04 13:23:49 29 4
gpt4 key购买 nike

大家下午好!

因此,我一直在尝试将 .NET 集合转换为功能数据结构的方法。我能得到的最好的结果就是先把它转换成一个序列,然后再转换成我想要的任何东西。

问题是这似乎破坏了类型推断,这显然是不安全的。

例子:

let a = new System.DirectoryServices.DirectorySearcher("<query>") in
let entries = a.FindAll ()
let entries_list =
let (entries_seq : seq<obj>) = Seq.cast entries_list in
Seq.toList entries_Seq
in
entries_list (* list of AD objects found from query, has type obj *)

为了对条目列表做任何有用的事情,我必须这样做:
entries_list :?> SearchResult

尝试将其概括为 seq<'a> 失败,因为编译器仍然要求我静态键入它的枚举数(这是有道理的)。

有没有办法避免这种情况?我开始认为这是以功能方式使用 .NET 数据结构的限制。

对不起,如果这是一个新手问题;总的来说,我对 F# 和函数式编程很熟悉(并且很喜欢它!)。干杯!
  • 卡洛斯。
  • 最佳答案

    正如丹尼尔所说,您通常不需要使用 Seq.cast因为大多数集合已经实现了泛型 seq<'t>界面。但是,在 .NET 2.0 中引入泛型之前构建了几种 .NET 集合类型,它们仅实现非泛型 IEnumerable界面。 F# 编译器实际上在 for 中有一些特殊的逻辑。循环称为“可枚举提取”,以使处理这些类型的集合更容易一些。因此,如果您只处理其中一种集合类型(例如,您正在使用 DirectoryServices.SearchResultCollections 很多),那么简单地创建一个简单的辅助函数可能是有意义的:

    let typedSearchResults (s:SearchResultCollection) =
    seq { for result in s -> result }

    然后您可以使用它来代替 Seq.cast对于这个特定的集合类型。

    如果您在同一个项目中使用许多不同的旧式集合,那么您可以使用一些花哨的 F# 功能来制作通用 Seq.cast选择:
    module Seq =
    let inline inferCast s =
    // constrain ^t to have an Item indexed property (which we don't actually invoke)
    let _ = fun x -> (^t : (member Item : int -> ^v with get) (x, 0))
    let e = (^t : (member GetEnumerator : unit -> ^e) s)
    seq { while (^e : (member MoveNext : unit -> bool) e) do
    yield (^e : (member Current : obj) e) :?> ^v }

    现在您可以使用 Seq.inferCast而不是 Seq.cast ,并且将为您推断正确的项目类型。不过,在您的情况下,这可能有点矫枉过正。

    关于.net - 有没有一种安全的方法可以将 Collection 转换为 F# 中的序列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13573029/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com