'base'值只能用于直接调用重写成员的基本实现

时间:2011-05-01 07:51:20

标签: inheritance f# override base derived

为什么我不能在此处调用base的{​​{1}}实现:

f

type Base = abstract f : int -> int -> int default this.f (x : int) (y : int) : int = x + y type Derived = inherit Base override this.f (x : int) (y : int) : int = base.f -x -y 的调用会引发此编译器错误:

base.f

如果我将error FS0419: 'base' values may only be used to make direct calls to the base implementations of overridden members 更改为单个参数,则编译。据推测,这与curried参数与tupled参数有关,但上面的代码对我来说很好。

3 个答案:

答案 0 :(得分:5)

我认为问题是关闭无法捕获base - 必须直接调用。但是,覆盖curried函数会自动创建闭包,因为只会立即应用第一个参数。因此,即使您确实使用base值来直接调用重写成员的基本实现,您实际上在闭包中使用base值,这是非法的。

不幸的是,我认为没有什么好方法可以解决这个问题。一般来说,你应尽可能避免使用curried成员,但这里有一个替代方案:

type Base = 
    abstract f : int -> (int -> int)
    default this.f (x : int) = fun y -> x + y

type Derived = 
    inherit Base
    override this.f x = 
       let fn = base.f -x
       fun y -> fn -y

答案 1 :(得分:0)

您对咖喱参数的假设是正确的。下面的代码编译并运行良好:

type Base () = 
    abstract f : int * int -> int
    default this.f (x : int,y : int) : int = x + y

   type Derived ()  = 
    inherit Base()
    override this.f (x : int,y : int) : int = 
        base.f(-x,-y)

注意:我使用了tupled参数。这个原因可能是因为在curried参数中它会破坏多个函数中的函数(每个函数需要1个参数)

答案 2 :(得分:0)

@kvb在他的分析中是正确的,但如果你真的想要覆盖一个curried方法,你可以。但语法非常冗长:

type Base = 
    abstract f : int -> (int -> int)
    default this.f (x : int) = fun (y : int) -> x + y

type Derived = 
    inherit Base
    override this.f (x : int) =
        let baseCall = base.f -x
        fun (y : int) -> baseCall -y