无法在VB.NET中递归调用函数

时间:2014-02-17 12:37:06

标签: vb.net recursion delegates

作为一个了解该语言的小程序,我试图在VB中实现linq Select方法(通常称为.net之外的Map),但似乎我遇到了一个小问题。问题,它不会让我递归调用函数,因为它认为类型不匹配

这是代码:

Iterator Function Map(Of A, B)(fun As Func(Of A, B), input As List(Of A)) As IEnumerable(Of B)
    If input Is Nothing Then
        Yield Nothing
    Else
        Yield fun(Head(input))
        Map(fun, Tail(input)) ' error here
    End If
End Function

请注意Head()是一个返回输入列表第一个元素的函数,而Tail()是一个返回所有内容的方法但是第一个元素

我之前做了一个测试,看看是否有可能将Func(Of A, B)传递给像我这样的函数;它工作得很好,所以为什么它现在不起作用我真的不知道......

任何人都可以帮忙吗?

1 个答案:

答案 0 :(得分:3)

我们假设HeadTail具有以下签名:

Function Head(Of T)(lst As IEnumerable(Of T)) As T
    ...
End Function

Function Tail(Of T)(lst As IEnumerable(Of T)) As IEnumerable(Of T)
    ...
End Function

然后该行产生以下错误(提示:始终在您的SO问题中包含错误消息。):

  

方法'Public Iterator Function Map(Of A,B)中的类型参数的数据类型(fun as System.Func(Of A,B),输入As System.Collections.Generic.List (Of A))因为System.Collections.Generic.IEnumerable(Of B)'不能从这些参数中推断出来。明确指定数据类型可能会纠正此错误。

所以让我们做错误信息:

Iterator Function Map(Of A, B)(fun As Func(Of A, B), input As List(Of A)) As IEnumerable(Of B)
    ...
        Map(Of A, B)(fun, Tail(input))
    ...
End Function

我们收到更具体的错误:

  

Option Strict On禁止从'System.Collections.Generic.IEnumerable(Of A)'到'System.Collections.Generic.List(Of A)'的隐式转换。

这是有道理的:Tail返回IEnumerableMap需要List。由于Map不使用任何特定于列表的属性,所以让我们在其输入中使Map更加自由:

Iterator Function Map(Of A, B)(fun As Func(Of A, B), input As IEnumerable(Of A)) As IEnumerable(Of B)
    ...
End Function

现在,一切都正确编译。实际上,我们现在可以再次删除 (Of A, B),因为修复数据类型允许VB.NET正确地推断出所需的泛型类型参数:

Iterator Function Map(Of A, B)(fun As Func(Of A, B), input As IEnumerable(Of A)) As IEnumerable(Of B)
    If input Is Nothing Then
        Yield Nothing
    Else
        Yield fun(Head(input))
        Map(fun, Tail(input)) ' works
    End If
End Function