【发布时间】:2011-11-23 16:47:09
【问题描述】:
以下 F# 代码声明基类和后代类。基类有一个带有默认实现的虚拟方法“Test”。后代类覆盖基类方法并添加一个新的重载“测试”方法。此代码编译良好,并且在访问任何一个后代“测试”方法时都不会出现问题。
F# 代码:
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 结果 = td.Test(3);
完整的 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# 重新实现了这个场景,并且没有遇到同样的问题。
有人知道这里发生了什么吗?
【问题讨论】:
-
您是否比较了两种语言发出的 IL?
-
我在反射器中看到的唯一奇怪的事情是基本方法显示为
override,而不是virtual。这似乎是因为基本方法没有newslot属性。 -
我认为这是 C# 编译器或 F# 编译器中的一个错误,但我不确定是哪一个(我猜是 C#)。
-
@svick -
Base方法中缺少newslot仅意味着如果 its 基类(在本例中为obj)被更改为具有正确签名的虚拟Test方法,Base.Test将覆盖它而不是隐藏它。我认为 F# 最好包含newslot以避免版本控制问题,但我不明白为什么在这种情况下会导致任何问题。 -
这可能是一个错误——我们将对其进行调查。感谢您的报告!唐娜·马拉里 (MSFT)
标签: c# f# interop overloading overriding