为什么该成员重写上的F#错误?

时间:2019-03-17 17:47:16

标签: inheritance f#

上下文:

我正在尝试创建几个类来封装SQL命令,使其比标准System.Data类更适合函数式编程。

我关心3种主要的SQL命令类型

  • 不返回任何内容的命令
  • 返回1行的命令
  • 返回许多行的命令

必须如何执行这些实现的实现略有不同,但是我希望它们都共享一个公共协定,这就是为什么我要使用类继承。我也可以使用接口,但是在这种情况下似乎没有太大的区别。

我已将共享合同作为此基础类实现:

[<AbstractClass>]
type ClosedCommand<'a>(text, kind, parameters) =
    inherit OpenCommand(text, kind, parameters)

    abstract member execute : cn:IDbConnection -> 'a

3个子类为:

type UnitCommand(text, kind, parameters) =
    inherit ClosedCommand<unit>(text, kind, parameters)

    override x.execute cn =
        let cmd = x.toCommandDefinition null
        SqlMapper.Execute(cn, cmd) |> ignore 

type SingleCommand<'a>(text, kind, parameters) =
    inherit ClosedCommand<'a>(text, kind, parameters)

    override x.execute cn =
        let cmd = x.toCommandDefinition null
        SqlMapper.QuerySingle<'a>(cn, cmd)

type PluralCommand<'a>(text, kind, parameters) =
    inherit ClosedCommand<seq<'a>>(text, kind, parameters)

    override x.execute cn =
        let cmd = x.toCommandDefinition null
        SqlMapper.Query<'a>(cn, cmd)

实现的核心是Dapper库中的SqlMapper类。

问题:

对于没有返回任何命令的命令,我在子类上遇到编译错误。这是屏幕截图:

screenshot

消息是:

成员execute : IDbConnection -> unit的类型不正确,无法覆盖相应的抽象方法。

在我看来,它确实具有正确的类型。即使我添加类型注释,它仍然会给出相同的错误。

这种情况与其他两种情况之间的唯一区别是,它将unit绑定到'a,而其他两种情况则保持通用。似乎并不重要。

最小示例:

[<AbstractClass>]
type CommandBase<'a>(name) =
    member this.Name : string = name
    abstract member Execute : unit -> 'a

type UnitCommand(name) =
    inherit CommandBase<unit>(name)
    override this.Execute () = ()

type SingleCommand<'a>(name, x) =
    inherit CommandBase<'a>(name)
    override this.Execute () = x 

type MultipleCommand<'a>(name, xs) =
    inherit CommandBase<seq<'a>>(name)
    override this.Execute () = xs

如何获取此文件?

0 个答案:

没有答案