【问题标题】:Error No default member found for type 'VB$AnonymousDelegate_0(Of SqlDataReader,String,Object)'.- Inline function错误找不到类型“VB$AnonymousDelegate_0(Of SqlDataReader,String,Object)”的默认成员。- 内联函数
【发布时间】:2012-01-12 13:34:45
【问题描述】:

我遇到了这个错误 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)

【问题讨论】:

  • 我使用的是 Visual Studio 2008

标签: .net vb.net visual-studio-2008


【解决方案1】:
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

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

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


编辑(委托和 lambda 表达式的解释):

Dim GetDataTableFromSQLReader As Func(Of SqlDataReader, String, DataTable)

您在一个称为“委托”的专用类中定义了一个变量,该变量可以保存一个函数,或者更准确地说是它的地址。就 .NET 而言,此变量是一个代表方法的委托(除非它是 Nothing)。根据上面的声明,这个函数必须接受一个SqlDataReader 类型的参数和一个String 类型的参数。返回值的类型必须是DataTable

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

GetDataTableFromSQLReader = AddressOf GetDataTableFromSQLDataReader

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

Dim DataTable dt = GetDataTableFromSQLReader(dr, "")

实际上这会调用分配给它的函数,即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

如您所见,我们打印了 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

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

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

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

PrintFunction(AddressOf Square)
PrintFunction(AddressOf Reciprocal)

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

PrintFunction(Function(x) x*x)
PrintFunction(Function(x) 1 / x)

【讨论】:

  • @Oliver 。谢谢 。我是 lamda 表达式的新手,你能提供更多细节吗?
  • 我添加了对委托和 lambda 表达式的简短说明。有关详细信息,请参阅 MSDN 上的 Lambda Expressions
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-21
  • 2023-03-02
  • 1970-01-01
  • 2021-08-20
  • 2020-06-19
  • 2020-08-30
相关资源
最近更新 更多