继承类型时获取“值未定义”

时间:2010-05-10 01:22:10

标签: inheritance f#

我无法看到我做错了什么,因为文件的顺序正确。在这种情况下,它是:

  1. BaseDAO.fs
  2. CreateDatabase.fs
  3. 它们位于相同的命名空间中,但即使我将它们放在不同的模块中,并在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
    

    继承的类型在这里,execNonQuery未定义。

    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))"
    

1 个答案:

答案 0 :(得分:5)

在F#中,只能通过成员的名称隐式调用继承的成员(以及当前类型中定义的成员) - 您需要以某种方式引用该类型的实例。在您的情况下,您可以使用base关键字。以下应该有效:

type CreateDatabase() = 
    inherit BaseDAO() 
    let createRestaurantTable conn = 
        base.execNonQuery "..."

[编辑] 仅当createRestaurantTablemember时才有效 - 不是使用let声明的函数(如上例所示)。原因是F#编译器不允许在闭包中使用caputring base并且它将上面的示例解释为闭包。你可以把它变成成员并写下:

type CreateDatabase() = 
    inherit BaseDAO() 
    private member x.createRestaurantTable conn = 
        x.execNonQuery "..."

<强> [/ EDIT]

或者,您也可以使用as self命名当前的类型实例(类似于在成员声明中使用member self.Foo() = ..指定实例。这也允许您调用当前类型的成员来自构造函数:

type CreateDatabase() as self = 
    inherit BaseDAO() 
    let createRestaurantTable conn = 
        self.execNonQuery "..."

如果可能的话,我更喜欢base关键字(因为引用构造函数中的当前实例会导致编译器出现各种麻烦)。