gpt4 book ai didi

c# - 无法解析已从 C# 重写和重载的 F# 方法

转载 作者:IT王子 更新时间:2023-10-29 04:35:12 26 4
gpt4 key购买 nike

以下 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 result = td.Test(3); <- No overload for method 'Test' takes 1 arguments

完整的 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 的 intellisense 看到了两个重载函数,并为它们提供了正确的签名。它在构建失败之前不会给出警告或错误,只会在之后突出显示该行。

我已经用 C# 完全重新实现了这个场景,没有遇到同样的问题。

有人知道这里发生了什么吗?

最佳答案

毫无疑问,如果您从 Descendant 类型中省略 Test(x,y) 成员,或者只是将其重命名为 Test2( x,y) -- 然后 C# 代码将按预期编译和运行。

查看为您的原始 Descendant 类型生成的 IL 提供了一条线索:

.method public hidebysig virtual
instance int32 Test (
int32 x
) cil managed ...

.method public
instance int32 Test (
int32 x,
int32 y
) cil managed ...

请注意 Test(x,y) 方法中没有 hidebysig 属性。

ECMA CLI specification关于 hidebysig 有以下说法。 (第 15.4.2.2 节,粗体强调是我的。)

hidebysig is supplied for the use of tools and is ignored by the VES. It specifies that the declared method hides all methods of the base class types that have a matching method signature; when omitted, the method should hide all methods of the same name, regardless of the signature.

因此,F# 编译器省略了 hidebysig 属性,这意味着 Test(x,y) 方法隐藏了所有其他名为 Test 的方法.虽然hidebysig只是“为了工具的使用”,但似乎C#编译器就是使用它的那些工具之一!

在我看来,这可能是 F# 编译器中的一个错误,但由于我从未看过 F# 规范,所以这总是可能被允许/指定的行为。

关于c# - 无法解析已从 C# 重写和重载的 F# 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8245948/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com