【问题标题】:How to return an object from a recursed function?如何从递归函数返回对象?
【发布时间】:2011-12-12 20:58:33
【问题描述】:

我需要浏览页面上的所有控件,寻找特定的控件。我们有一堆用户控件、母版页、内容面板等等。

基本思想很简单,但是一旦我找到我想要的控件,比如五个“层”,控件只返回一层。

我知道我可以做一些俗气的事情,比如拥有一个私有变量并将控制权分配给兔子洞中的那个,但我认为必须有更正式的方法来做到这一点。

还有,这就是所谓的尾递归吗?

我们使用的是 3.5 框架。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim c As Control = getNamedControl(Page, "tb")
End Sub


Private Function getNamedControl(ByVal root As Control, ByVal theTarget As String) As Control
    If root.Controls.Count < 1 Then
        If Not IsNothing(root.ID) Then
            If root.ID = theTarget Then
                Return root
            End If
        End If
    Else
        For Each c As Control In root.Controls
            If c.ID = theTarget Then
                Return c
            Else
                getNamedControl(c, theTarget)
            End If
        Next
    End If
End Function

【问题讨论】:

    标签: vb.net recursion asp.net-3.5


    【解决方案1】:
    Public Module WebControlExtensions
        ' Can be used to find controls recursively that won't be found via Page.FindControl 
        ' because they are nested in other NamingContainers 
        ' Example: Dim ctrl = Page.FindControlRecursive("tb") '
        <Runtime.CompilerServices.Extension()>
        Public Function FindControlRecursive(ByVal rootControl As Web.UI.Control, ByVal controlID As String) As Web.UI.Control
            If rootControl.ID = controlID Then
                Return rootControl
            End If
    
            For Each controlToSearch As Web.UI.Control In rootControl.Controls
                Dim controlToReturn As Web.UI.Control = FindControlRecursive(controlToSearch, controlID)
                If controlToReturn IsNot Nothing Then
                    Return controlToReturn
                End If
            Next
            Return Nothing
        End Function
    End Module
    

    该函数会在找到控件后立即返回。

    我们有一堆用户控件、母版页、内容面板...

    您确定使用递归函数查找控件是个好主意吗?特别是如果您在 MasterPage 的 ContentPages 的页面中使用具有相同 ID 的 UserControls,您可能会发现错误的控件。这很容易出错。

    除了您将用户控件与他们的页面与他们的 MasterPage 硬连接之外,封装和可重用性的反面是什么。

    【讨论】:

    • 我只是在喝杯咖啡,我的解决方案是在办公室,所以我还不能消化这个。但是,感谢您的回复,甚至更多关于这是否是解决此问题的最佳方法的深思熟虑的问题。我觉得我总是要学习更多东西——设计方法和考虑是无限的,而语言和技术虽然广泛,但在某些时候是有限的。
    • 我必须承认我根本不需要使用我自己的递归函数。您应该首先了解控件是如何相互嵌套的,了解控件的NamingContainers 是什么。然后你知道如何以正确的方式(直接)获得对控件的引用。然后学习how UserControls should communicate with their pages(and vice-versa),页面及其母版等等。
    【解决方案2】:
        If c.ID = theTarget Then
            Return c
        Else
            getNamedControl(c, theTarget)
        End If
    

    变成:

        If c.ID = theTarget Then
            Return c
        Else
            Dim d as Control
            d = getNamedControl(c, theTarget)
            If Not IsNothing(d) Then
               return d
            End If
        End If
    

    那么就在函数结束之前:

      return Null
    

    编辑:

    假设返回值被检查,这不是尾递归。

    见:http://en.wikipedia.org/wiki/Tail_call 搜索“foo3”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      相关资源
      最近更新 更多