Inheritance 获得;“未定义值”;继承类型时
我看不出我做错了什么,因为文件的顺序是正确的。在这种情况下,它是:Inheritance 获得;“未定义值”;继承类型时,inheritance,f#,Inheritance,F#,我看不出我做错了什么,因为文件的顺序是正确的。在这种情况下,它是: BaseDAO.fs CreateDatabase.fs 它们在同一个名称空间中,但即使我将它们放在不同的模块中,并且在CreateDatabase中打开模块时也会出现相同的错误 错误是: Error 1 The value or constructor 'execNonQuery' is not defined 我正在尝试继承BaseDAO并使用一个对多个文件通用的成员,我不明白为什么会出现上述错误 namesp
CreateDatabase
中打开模块时也会出现相同的错误
错误是:
Error 1 The value or constructor 'execNonQuery' is not defined
我正在尝试继承BaseDAO
并使用一个对多个文件通用的成员,我不明白为什么会出现上述错误
namespace RestaurantServiceDAO
open MySql.Data.MySqlClient
type BaseDAO() =
let connString = @"Server=localhost;Database=mysql;Uid=root;Pwd=$$$$;"
let conn = new MySqlConnection(connString)
member self.execNonQuery(sqlStr) =
conn.Open()
let comm = new MySqlCommand(sqlStr, conn, CommandTimeout = 10)
comm.ExecuteNonQuery |> ignore
comm.Dispose |> ignore
此处是继承的类型,未定义execonquery
namespace RestaurantServiceDAO
open MySql.Data.MySqlClient
type CreateDatabase() =
inherit BaseDAO()
let createRestaurantTable conn =
execNonQuery "CREATE TABLE restaurant(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), cur_timestamp TIMESTAMP(8))"
在F#中,继承的成员(以及在当前类型中定义的成员)不能仅通过成员的名称隐式调用-您需要以某种方式引用该类型的实例。在您的情况下,可以使用base
关键字。以下方面应起作用:
type CreateDatabase() =
inherit BaseDAO()
let createRestaurantTable conn =
base.execNonQuery "..."
[EDIT]只有当createRestaurantTable
是成员时,此功能才有效,而不是使用let
声明的函数(如上面的示例所示)。原因是F#编译器不允许在闭包中使用caputringbase
,它将上面的示例解释为闭包。您可以将其转换为成员并写入:
type CreateDatabase() =
inherit BaseDAO()
private member x.createRestaurantTable conn =
x.execNonQuery "..."
[/EDIT]
或者,您也可以使用将该类型的当前实例命名为self
(这类似于在成员声明中使用成员self.Foo()=..
指定实例。这还允许您从构造函数调用当前类型的成员:
type CreateDatabase() as self =
inherit BaseDAO()
let createRestaurantTable conn =
self.execNonQuery "..."
如果可能的话,我更喜欢base
关键字(因为在构造函数中引用当前实例会给编译器带来各种各样的麻烦).我不能使用base.execonquery,因为它抱怨闭包,但我确实将它们变成了成员,这解决了我的问题。谢谢you@James:你说得对-base
不能在let
绑定函数中使用。这有点不公平-添加作为self
可能是另一种选择(它生成一些运行时检查,以确保初始化是正确的,并且在类完全初始化之前不使用self
,但这应该不是什么大问题)。