2013-12-08 35 views
0

請參考下面的代碼:產量與代表

Public Iterator Function Read(Of T)(ByVal sql As String, ByVal make As Func(Of IDataReader, T), ParamArray ByVal parms() As Object) As IEnumerable(Of T) 
      Using connection = CreateConnection() 
       Using command = CreateCommand(sql, connection, parms) 
        Using reader = command.ExecuteReader() 
         Do While reader.Read() 
          Yield make(reader) --line 7 
         Loop 
        End Using 
       End Using 
      End Using 
     End Function 

Private Shared Make As Func(Of IDataReader, Member) = 
      Function(reader) _ 
       New Member() With { 
        .MemberId = Extensions.AsId(reader("MemberId")), 
        .Email = Extensions.AsString(reader("Email")), 
        .CompanyName = Extensions.AsString(reader("CompanyName")), 
        .City = Extensions.AsString(reader("City")), 
        .Country = Extensions.AsString(reader("Country")) 
       } 

請參見線7.進行填充型部件的一個目的與來自所述數據讀取器行值。我已閱讀以下文檔:http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx。該文檔似乎無法解釋您使用委託時發生的情況,即Yield make(datareader),而不是Yield return datareader。控制傳遞給調用函數以及委託(Make)?

回答

0

Make(reader)Make.Invoke(reader)的快捷方式。即,你

  • 調用委託,傳遞reader作爲參數,它的值爲Member
  • 然後,您使用Yield返回該值。

它等效於:

... 
    Do While reader.Read() 
     Dim myMember As Member = make(reader) 
     Yield myMember 
    Loop 
... 

PS:如果您在代碼中得到一個編譯時錯誤(你不要在你的問題說的話):這是由於這樣的事實:您的方法被聲明爲返回IEnumerable(Of T),實際上它返回IEnumerable(Of Member)

+0

make委託運行後,成員放置的對象在哪裏?我期望控制權被傳回給make後運行的函數,但這似乎並非如此。 – w0051977

+0

@ w0051977:如果'Member'是一個類:在堆上。如果它是一個結構體:可能在堆棧中。不過,這應該沒有什麼不同。是否以及如何返回控制可能取決於調用代碼:如果您只調用Dim x = Read(),控制將立即返回*(甚至在執行第一行Read之前)。如果你調用'Dim x = Read()。ToList()','Read'將在返回前完全執行。如果你在Read()中使用'For Each x',執行'Read'將會和你的循環鎖定在一起。 – Heinzi

+0

@ w0051977:我確信你在這裏錯了。你的問題在於別處,它與你使用委託無關(嘗試用一個常規函數替換委託來說服你自己)。 – Heinzi