为什么这个看似正确的.net代码不能编译?
本文关键字:代码 net 不能 编译 为什么 | 更新日期: 2023-09-27 18:12:17
我是在问,以防我错过了一些明显的东西,但我想我可能偶然发现了。net编译器中的一个错误。
我在。net解决方案中有两个项目,一个visual basic,一个c#。
c#代码,由三个重载的静态方法组成,它们具有默认值:
public static class Class1
{
public static void TestFunc(int val1, int val2 = 0)
{
}
public static void TestFunc(int val1 = 0)
{
}
public static void TestFunc(string val1, int val2 = 0)
{
}
}
Visual basic代码,调用重载方法之一:
Option Explicit On
Option Strict On
Imports ClassLibrary1
Module Module1
Sub Main()
Dim x As Integer
Class1.TestFunc(x, 0)
End Sub
End Module
编译此代码将失败,显示:
'TestFunc'是二义性的,因为在类' classlibrary . class1 '中存在多种具有此名称的成员。
为什么它会认为这个方法有歧义?只有一个Class1。带有(int, int)签名的TestFunc。这是一个错误,还是我错过了什么?
最终,这似乎归结为c#如何在您的第一个静态方法中实现可选参数。如果您删除了它的默认值,那么您的解决方案应该可以编译。
public static void TestFunc(int val1, int val2)
{
}
实际上,在这种情况下,我有点惊讶c#编译。在c#中,要么使用可选参数,要么使用重载,但不能两者都使用。例如,如何消除以下内容的歧义:
public static void TestFunc(int val1, int val2 = 0)
{
}
public static void TestFunc(int val1)
{
}
如果我传入以下内容,应该执行两个方法中的哪一个-带可选参数的方法还是不带第二个参数的方法?
TestFunc(1)
如果你想在c#实现中包含可选参数,一个更好的解决方案是将第一个和第二个方法结合起来,并在必要时检查默认值:
public static void TestFunc(int val1, int val2 = 0)
{
}
public static void TestFunc(string val1, int val2 = 0)
{
}
注意,使用这个版本,VB能够消除调用哪个方法的歧义。
如果你尝试在VB中编译这个。你会得到
Sub TestFunc(ByVal val1 As Integer, Optional ByVal val2 As Integer = 0)
End Sub
Sub TestFunc(Optional ByVal val1 As Integer = 0)
End Sub
你会得到Public Sub TestFunc(val1 As Integer, [val2 As Integer = 0])' and 'Public Sub TestFunc([val1 As Integer = 0])' cannot overload each other because they differ only by optional parameters.
所以我说VB。. NET在可选参数重载方面比c#更受限制。
TestFunc是不明确的,因为默认参数。当TestFunc(x)被调用时,它不确定它是调用TestFunc与单个参数还是TestFunc与默认的2个参数,第二个参数是默认的一个。
编辑
当这个问题第一次发布时:
Option Strict On
和
Option Explicit On
并没有出现在问题中,所以这极大地改变了答案。
问题编辑前的原始答案
因为这个:
public static void TestFunc(int val1, int val2 = 0)
{
}
歧义为:
public static void TestFunc(string val1, int val2 = 0)
{
}
VB.net可以将整数转换为字符串
在Visual Basic语言规范10中声明。
具有可选参数的方法被认为具有多个参数签名,每组参数一个,可以传入调用者。例如,下面的方法有三个对应的签名:
Sub F(x As Short, _
Optional y As Integer = 10, _
Optional z As Long = 20)
所以你的TestFunc(int val1, int val2 = 0)
在VB中有两个签名,这与TestFunc(int val1)
冲突,所以TestFunc
是不明确的。
我在c#规范中找不到任何东西说可选参数被视为具有多个签名的方法。从你看到的行为来看,我假设在c#中它们不被认为有多个签名,否则你会得到一个编译器错误——这意味着它在c#中是有效的。我认为c#将根据一些规则选择调用的方法,因为它不能同时调用TestFunc(0)
。