以下是F#代码,声明了一个基类和一个派生类。基类有一个虚方法'Test'并有一个默认实现,而派生类则重写了基类的方法,并添加了一个新的重载'Test'方法。这段代码编译时没有问题,而且访问派生类中的任意一个'Test'方法也不会有任何问题。
module OverrideTest
[<AbstractClass>]
type Base() =
abstract member Test : int -> int
default this.Test x = x + 1
type Descendant() =
inherit Base()
override this.Test x = x - 1
member this.Test (x, y) = x - y
尝试从C#调用子类对'Test'的重写会导致编译错误:
var result = td.Test(3); <- 没有接受1个参数的方法“Test”的重载
完整的C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Client
{
class Program
{
static void Main(string[] args)
{
var td = new OverrideTest.Descendant();
var result = td.Test(3);
Console.WriteLine(result);
Console.ReadKey();
}
}
}
奇怪的是,VisualStudio 的智能感知看到了这两个重载函数,并为两者提供了正确的签名。在构建失败之前,它没有给出任何警告或错误提示,只有在之后才会突出显示该行。
我已经完全在C#中重新实现了这种情况,并且没有遇到同样的问题。
有人知道这里发生了什么吗?
Base
方法缺少newslot
只意味着如果 它的 基类(在本例中为obj
)更改为具有正确签名的虚拟Test
方法,则Base.Test
将覆盖它而不是隐藏它。我认为 F# 最好包含newslot
以避免版本问题,但我看不出这会在这种情况下引起任何问题。 - kvb