此表达式应具有 IDataReader 类型,但此处具有 SqlDataReader 类型
this expression was expected to have type IDataReader but here has type SqlDataReader
以下代码在调用 Seq.unfold
时没有将 SqlDataReader
的 return 值从 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
F# 不会像 C# 那样自动向上转型,除了在某些特定情况下(参见 spec,第 14.4.2 节)。
您必须显式转换表达式:cmd.ExecuteReader() :> IDataReader
然后您可以删除 getReader
之后的类型注释。
或者,您可以让该函数返回 SqlDataReader
并在调用站点向上转换:
let foos = getReader :> IDataReader |> Seq.unfold iterFoo
如果 unfold
是具有如下签名的类型的静态成员:
type T() =
static member unfold(a, b:IDataReader) = Seq.unfold a b
你可以直接 T.unfold(iterFoo, getReader)
并且它会自动向上转换。这是规范中提到的情况之一。
以下代码在调用 Seq.unfold
时没有将 SqlDataReader
的 return 值从 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
F# 不会像 C# 那样自动向上转型,除了在某些特定情况下(参见 spec,第 14.4.2 节)。
您必须显式转换表达式:cmd.ExecuteReader() :> IDataReader
然后您可以删除 getReader
之后的类型注释。
或者,您可以让该函数返回 SqlDataReader
并在调用站点向上转换:
let foos = getReader :> IDataReader |> Seq.unfold iterFoo
如果 unfold
是具有如下签名的类型的静态成员:
type T() =
static member unfold(a, b:IDataReader) = Seq.unfold a b
你可以直接 T.unfold(iterFoo, getReader)
并且它会自动向上转换。这是规范中提到的情况之一。