2012-01-12 47 views
0

我有这个错误 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

我正在使用Visual Studio 2008 – kbvishnu 2012-01-12 13:39:44

回答

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 StrictOn。它会帮助你声明正确的类型。例如,你的函数没有声明返回类型。这可能是错误的主要来源。

您的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) 
+0

@Oliver。谢谢 。我是lamda表达新手,你能提供更多的细节吗? – kbvishnu 2012-01-13 05:19:04

+1

我为代表和lambda表达式添加了一个简短的解释。有关更多信息,请参见MSDN上的[Lambda表达式](http://msdn.microsoft.com/zh-cn/library/bb531253.aspx)。 – 2012-01-13 14:01:50

+0

@oliver感谢您的解释.. – kbvishnu 2012-01-13 21:04:31