继承类型时获取"值未定义"

Jam*_*ack 3 inheritance f#

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

  1. BaseDAO.fs
  2. CreateDatabase.fs

它们位于相同的命名空间中,但即使我将它们放在不同的模块中,并CreateDatabase以相同的错误打开模块.

错误是:

Error   1   The value or constructor 'execNonQuery' is not defined  
Run Code Online (Sandbox Code Playgroud)

我试图继承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
Run Code Online (Sandbox Code Playgroud)

继承的类型在这里,并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))"
Run Code Online (Sandbox Code Playgroud)

Tom*_*cek 5

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

type CreateDatabase() = 
    inherit BaseDAO() 
    let createRestaurantTable conn = 
        base.execNonQuery "..."
Run Code Online (Sandbox Code Playgroud)

[编辑]这仅createRestaurantTable适用于member- 不是使用声明的函数let(如上例所示).原因是F#编译器不允许base在闭包中进行限制,并且它将上面的示例解释为闭包.你可以把它变成成员并写:

type CreateDatabase() = 
    inherit BaseDAO() 
    private member x.createRestaurantTable conn = 
        x.execNonQuery "..."
Run Code Online (Sandbox Code Playgroud)

[/编辑]

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

type CreateDatabase() as self = 
    inherit BaseDAO() 
    let createRestaurantTable conn = 
        self.execNonQuery "..."
Run Code Online (Sandbox Code Playgroud)

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