错误找不到类型'VB $ AnonymousDelegate_0(Of SqlDataReader,String,Object)'的默认成员。-内联函数

kbv*_*hnu 1 .net vb.net visual-studio-2008

我有这个错误 No default member found for type 'VB$AnonymousDelegate_0(Of SqlDataReader,String,Object)'.

我的代码如下

dsBranch.Tables.Add(GetDataTableFromSQLReader(dr, "")) -打电话

Private Function GetDataTableFromSQLDataReader(ByVal dr As SqlDataReader, ByVal TableName As String)
    Dim dt As New DataTable(TableName)
    dt.Load(dr)
    Return dt
End Function
Dim GetDataTableFromSQLReader = Function(dr As SqlDataReader, TableName As String) GetDataTableFromSQLDataReader(dr, TableName)
Run Code Online (Sandbox Code Playgroud)

Oli*_*bes 5

Imports System.Data
Imports System.Data.SqlClient

Public Class NoDefaultMemberFoundError

    ' Added "As DataTable"
    Private Function GetDataTableFromSQLDataReader(ByVal dr As SqlDataReader, _
                                                   ByVal TableName As String) As DataTable
        Dim dt As New DataTable(TableName)
        dt.Load(dr)
        Return dt
    End Function

    ' This is how it has to be declared
    Dim GetDataTableFromSQLReader As Func(Of SqlDataReader, String, DataTable) = _
                       Function(dr, TableName) GetDataTableFromSQLDataReader(dr, TableName)

    Sub Test()
        Dim dsBranch As DataSet = Nothing
        Dim dr As SqlDataReader = Nothing

        dsBranch.Tables.Add(GetDataTableFromSQLReader(dr, ""))
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

您应该将设置Option StrictOn。这将帮助您声明正确的类型。例如,您的Function没有声明返回类型。这可能是错误的主要来源。

您的Lambda分配也不正确。Lambda表达式始终必须分配给具体类型。这使编译器可以推断出它们的确切签名。


编辑(委托和lambda表达式的说明):

Dim GetDataTableFromSQLReader As Func(Of SqlDataReader, String, DataTable)
Run Code Online (Sandbox Code Playgroud)

您可以在一个称为“委托”的特殊类中定义一个变量,该变量可以包含一个函数,或更确切地说,可以包含其地址。就.NET而言,此变量是一个引用方法的委托(除非它是Nothing)。根据上面的声明,此函数必须接受type的一个参数和type的SqlDataReader一个String。返回值必须是类型DataTable

您可以将具有此请求的签名的任何函数分配给变量:

GetDataTableFromSQLReader = AddressOf GetDataTableFromSQLDataReader
Run Code Online (Sandbox Code Playgroud)

是有效的分配。(我可以用这种方式在原始答案中简化示例。)现在,您可以像使用函数一样使用变量了:

Dim DataTable dt = GetDataTableFromSQLReader(dr, "")
Run Code Online (Sandbox Code Playgroud)

实际上,这调用分配给它的函数GetDataTableFromSQLDataReader。如果我们想以不同的方式获取数据表,这是有道理的。我们可以给GetDataTableInADifferentWay变量分配另一个函数。GetDataTableFromSQLReader(dr, "")然后,该调用将调用该另一个函数,而在我们调用它时无需具有If-Then-Else语句。

现在,绕过代表,绕到lambda表达式。让我们举一个更合适的例子。我们要打印一个带有函数值的表:

Public Sub PrintFunction()
    For Dim x As Double = 1 To 10
        Console.WriteLine("x = {0}, f(x) = {1}", x, x*x)
    Next
End Sub
Run Code Online (Sandbox Code Playgroud)

如您所见,我们打印1到10的平方。但是,打印其他功能呢?PrintFunction每次需要打印其他功能时,我们都必须更改。在这里,代表们参加了比赛。让我们将声明更改为

Public Sub PrintFunction(Func(Of Double, Double) f)
    For Dim x As Double = 1 To 10
        Console.WriteLine("x = {0}, f(x) = {1}", x, f(x))
    Next
End Sub
Run Code Online (Sandbox Code Playgroud)

现在让我们声明一个平方函数和一个倒数函数

Public Function Square(x As Double) As Double
    Return x*x
End Function

Public Function Reciprocal(x As Double) As Double
    Return 1 / x
End Function
Run Code Online (Sandbox Code Playgroud)

现在我们可以打印两个不同的价值表

PrintFunction(AddressOf Square)
PrintFunction(AddressOf Reciprocal)
Run Code Online (Sandbox Code Playgroud)

我们还没有使用过lambda表达式。它们只是动态声明委托(或函数,如果您愿意)的一种非常简洁的方法。除了声明一个平方和一个倒数函数,我们可以这样打印表:

PrintFunction(Function(x) x*x)
PrintFunction(Function(x) 1 / x)
Run Code Online (Sandbox Code Playgroud)