下面的代码没有在调用SqlDataReader时正确地将getReader的返回值转换为IDataReader。我做错什么了?
open System.Data
open System.Data.SqlClient
open System.Configuration
type Foo = { id:int; name:string }
let populateFoo (r:IDataReader) =
let o = r.GetOrdinal
{ id = o "id" |> r.GetInt32; name = o "name" |> r.GetString; }
let iter populateObject (r:IDataReader) =
match r.Read() with
| true -> Some(populateObject r, r)
| _ -> None
let iterFoo = iter populateFoo
let getReader : IDataReader =
let cnstr = ConfigurationManager.ConnectionStrings.["db"].ConnectionString
let cn = new SqlConnection(cnstr)
let cmd = new SqlCommand("select * from Foo", cn)
cmd.ExecuteReader()
let foos = Seq.unfold iterFoo getReader发布于 2015-01-09 21:00:48
F#不像C#那样自动上传,除非在某些特定的场景中(参见等级库,第14.4.2节)。
您必须显式转换表达式:cmd.ExecuteReader() :> IDataReader,然后可以在getReader之后删除类型注释。
或者,您可以将该函数保留为在调用站点返回一个SqlDataReader和upcast:
let foos = getReader :> IDataReader |> Seq.unfold iterFoo如果unfold是具有类似于此签名的类型的静态成员:
type T() =
static member unfold(a, b:IDataReader) = Seq.unfold a b您将能够直接做T.unfold(iterFoo, getReader),它将自动上播。这是规范中提到的案例之一。
https://stackoverflow.com/questions/27868854
复制相似问题