【发布时间】:2011-07-06 22:05:47
【问题描述】:
我有如下函数,感觉有点奇怪。可能有一个我正在复制的习语或模式已经内置。该函数应该延迟返回加载的程序集及其引用。在每次调用时,它应该返回迄今为止发现的程序集的完整列表,以及新“发现”的程序集,直到迭代停止。有没有更好的写法?
let discoverAssemblies =
let known = HashSet()
let rec discover (assemblies:array<Assembly>) =
seq {
for asm in assemblies do
if known.Add(asm) then
yield asm
let refs =
asm.GetReferencedAssemblies()
|> Array.map (fun asmName -> Assembly.Load(asmName))
yield! discover refs
}
fun () ->
seq {
for asm in known do yield asm
yield! AppDomain.CurrentDomain.GetAssemblies() |> discover
}
顺便说一句,我还没有测试过它,它很有可能是错误的。因此更多地依赖描述而不是代码。
编辑
似乎LazyList 或Seq.cache 是合适的,但GetAssemblies() 是不确定的。但是,似乎一旦加载了所有引用的程序集,GetAssemblies() 将返回与GetReferencedAssemblies() 的递归遍历相同的内容。谁能证实这一点?如果是这样,更直接的解决方案是可能的。
【问题讨论】:
-
LazyList或Seq.cache将帮助您编写此代码,而无需将生成的程序集存储在HashSet中(您可以递归访问到目前为止生成的程序集以测试您是否已经生成了该程序集) .但是,使用HashSet效率更高,因此它似乎是一种更好的方法。
标签: reflection f#