2010-06-06 65 views
4
let reader = selectCommand.ExecuteReader() 

let getBytesData (x : IDataReader) = 
    let len = reader.GetBytes(1, int64 0, null, 0, 0); 
    // Create a buffer to hold the bytes, and then 
    // read the bytes from the DataTableReader. 
    let buffer : byte array = Array.zeroCreate (int32 len) 
    x.GetBytes(1, int64 0, buffer, 0, int32 len) |> ignore 
    buffer 

let retVal = 
    List [ while reader.Read() do 
      yield (reader.GetString(0), getBytesData reader, 
        reader.GetDateTime(2)) ] 

我有上面的代碼從datareader讀取字節[]。F#與DataReader配合使用

getBytesData函數將讀取器讀取並返回來自reader的字節[]。

  • 一切工作正常,但它getBytesData函數工作非常無功能的方式。
  • 我很創建零填充的字節數組只是創建數組,是有創建動態擴張或固定lenght陣列

的任何方式有什麼辦法,我可以在F#優化?

對不起樣的問題,但我已經開始對F#一個新的項目,以榨取所有果汁出來的,所以試圖讓每一行最優化的方式

+0

使用零初始化數組是沒有問題的 - 所有CLR數組始終在分配零初始化,沒有選項來獲得一個未初始化一個爲「填寫「後。 – 2010-06-07 04:20:37

回答

7

IDataReaderGetBytes方法並沒有真正提供任何用更有效的方式編寫代碼的選項(它需要一個要修改的數組,因此我們只需要給它一些數組......)。

因此,您的代碼版本非常好 - 即使功能不全面,您至少可以將命令部分保留在該單一功能中,並保持程序的其餘部分正常運行(這是一個好結果)!

我會在你的代碼中做的唯一改變是我將reader移動到序列理解(使它更加本地化),我會使用use關鍵字來確保它被妥善處置(也是,你不要「T需要在序列表達的List標識符):

let retVal = 
    [ use reader = selectCommand.ExecuteReader() 
    while reader.Read() do 
     yield (reader.GetString(0), getBytesData reader, reader.GetDateTime(2)) ] 
0

在我的經驗,是最好的辦法做這個。與原生.Net方法交互需要使用某種程度上的emparitiviley(因此忽略),所以封裝在函數中,然後使用fn作爲函數式編程的一部分。如果您有興趣,我已經提出了有關在F#中使用.Net方法的問題。

此外,請確保您事後處置讀者。