我有这个错误
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)
答案 0 :(得分:4)
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表达式分配给具体类型。这使编译器能够推断出它们的确切签名。
EDIT(代理和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)