实现递归查找扩展方法的问题

时间:2014-05-17 02:22:32

标签: asp.net vb.net recursion

我试图在VB.net中实现一个递归扩展方法,它会找到具有某个属性集的所有对象,所以我可以像这样调用它...

Dim camp As New CampaignStructure 'Populated with a full structure of course
Dim lstFoundItems As List(Of CategoryStructure) = camp.Categories.FindRecursive((Function(c) c.Found = False), 3)

我的VB.Net classess和模块目前看起来像这样

Imports System.Runtime.CompilerServices

Namespace MyStructure
Public Class CategoryStructure
    Public Property CategoryID As Integer = Nothing
    Public Property Name As String
    Public Property Rank As Integer
    Public Property Found As Boolean = False
    Public Property Children As New List(Of CategoryStructure)
End Class

Public Class CampaignStructure
    Public Property CampaignID As String = Nothing
    Public Property Categories As List(Of CategoryStructure)
End Class

Public Module ControlExtensions
    <Extension()> _
    Public Function FindRecursive(cs As List(Of CategoryStructure), predicate As Func(Of CategoryStructure, Boolean), depthLimit As Integer) As List(Of CategoryStructure)
        If cs Is Nothing OrElse cs.Count = 0 Then
            Return New List(Of CategoryStructure)()
        End If

        If depthLimit = 0 Then
            Return cs.OfType(Of CategoryStructure)().Where(predicate).ToList()
        Else
            '**ERROR IS THROWN HERE**
            Return cs.OfType(Of CategoryStructure)().Where(predicate).ToList().Union(cs.Cast(Of CategoryStructure).Select(Of List(Of CategoryStructure))(Function(c) c.Children.FindRecursive(predicate, depthLimit - 1)).ToList())
        End If
    End Function

End Module

End Namespace

但是当我将递归结果与标记代码中的当前列表结合起来时,我遇到了转换问题。我可以看到为什么会这样,只是不知道如何解决它。请不要向我发送C#示例,因为VB.net中没有'yield'替代方案

1 个答案:

答案 0 :(得分:0)

那是因为UNION的双方都有不同的签名。

cs.OfType(Of CategoryStructure)().Where(predicate).ToList()

返回List(Of CategoryStructure)

cs.Cast(Of CategoryStructure).Select(Of List(Of CategoryStructure))(Function(c) c.Children.FindRecursive(predicate, depthLimit - 1)).ToList()

这个返回List(Of List(Of CategoryStructure))

我认为您正在寻找的是:

Return cs.OfType(Of CategoryStructure)().Where(predicate).Union(cs.Cast(Of CategoryStructure).SelectMany(Function(c) c.Children.FindRecursive(predicate, depthLimit - 1))).ToList()

SelectMany返回标记为IEnumerable(Of CategoryStructure)的拼合集合。