2010-06-06 44 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方法的问题。

此外,请确保您事后处置读者。