.NET 4.8中Traverse函数异常处理及InvalidCastException排查
问题分析与解决方案
首先,你遇到的InvalidCastException和Return di.GetDirectories()的问题,核心是委托类型不匹配加上异常处理逻辑没达到预期,咱们一步步拆解:
1. 调用Traverse时的参数错误(直接导致InvalidCastException)
你的Traverse方法第二个参数要求的是Func(Of T, IEnumerable(Of T))——也就是一个「接受DirectoryInfo,返回目录集合」的函数委托,但你现在传的是funcGetDirectories(dinfo),这是直接执行了函数,返回的是DirectoryInfo()数组,而不是函数本身的引用。
VB.NET里要传递函数委托,得用AddressOf关键字,把函数转换为对应的委托类型。
2. funcGetDirectories的两个问题
- 返回类型未显式声明:虽然VB会自动推断,但显式声明为
IEnumerable(Of DirectoryInfo)能让代码更清晰,也避免潜在的类型问题。 - 异常处理无效:你现在捕获异常后直接
Throw,相当于没处理——遇到无权限目录还是会中断遍历,完全起不到跳过不可访问目录的作用。应该在捕获UnauthorizedAccessException时返回空集合,让遍历继续执行。
修正后的完整代码
1. 修正funcGetDirectories函数
Function funcGetDirectories(di As DirectoryInfo) As IEnumerable(Of DirectoryInfo) Try Return di.GetDirectories() Catch ex As UnauthorizedAccessException ' 遇到无权限的目录,返回空集合,让遍历跳过这个目录继续 Return Enumerable.Empty(Of DirectoryInfo)() Catch ex As Exception ' 其他异常也可以选择返回空集合,或者根据需求处理 Return Enumerable.Empty(Of DirectoryInfo)() End Try End Function
2. 修正Main方法中的调用
Friend Sub Main() Dim curDirectory As String = "你的目标目录路径" ' 替换成实际要遍历的目录 Dim dinfo As DirectoryInfo = New DirectoryInfo(curDirectory) ' 使用AddressOf传递函数委托,而不是执行函数后的结果 Dim dquery = RecursiveEnumerableExtensions.Traverse(dinfo, AddressOf funcGetDirectories) ' 示例:遍历输出所有可访问的目录 For Each dir In dquery Console.WriteLine(dir.FullName) Next End Sub
为什么这样能解决问题?
- 用
AddressOf funcGetDirectories传递委托,让Traverse方法可以在遍历每个目录时动态调用这个函数,而不是一开始就执行一次。 - 返回空集合替代抛出异常,遇到不可访问目录时,
Traverse会跳过该目录的子目录,继续处理其他可访问的路径,不会中断整个遍历流程。
内容的提问来源于stack exchange,提问作者Baku Bakar
相关产品推荐
相关产品推荐

