为什么这个看似正确的.NET代码不能编译?

w.b*_*ian 29 .net c# vb.net static-analysis

我问的是,我错过了一些明显的东西,但我想我可能偶然发现了.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)
    { 
    }
}
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

编译此代码将失败,说:

'TestFunc'是不明确的,因为类'ClassLibrary1.Class1'中存在多种具有此名称的成员.

为什么它会看到这种方法含糊不清?只有一个带有(int,int)签名的Class1.TestFunc.这是一个错误,还是我错过了什么?

Jim*_*ley 23

最终,它似乎归结为C#如何在第一个静态方法中实现可选参数.如果删除默认值,则应该编译解决方案.

public static void TestFunc(int val1, int val2) 
{ 
} 
Run Code Online (Sandbox Code Playgroud)

实际上,在这种情况下,我对C#编译感到有些惊讶.您应该在C#中使用可选参数或重载,但不能同时使用两者.例如,您将如何消除以下歧义:

public static void TestFunc(int val1, int val2 = 0)     
{     
}     

public static void TestFunc(int val1)     
{     
}  
Run Code Online (Sandbox Code Playgroud)

如果我传入以下内容,应该执行两种方法中的哪一种 - 带有可选参数的方法或没有第二个参数的第二种方法?

TestFunc(1)
Run Code Online (Sandbox Code Playgroud)

如果要在C#实现中包含可选参数,更好的解决方案是组合第一种和第二种方法,并根据需要检查默认值:

public static void TestFunc(int val1, int val2 = 0)
{
}

public static void TestFunc(string val1, int val2 = 0)
{
}
Run Code Online (Sandbox Code Playgroud)

注意,使用此版本,VB IS能够消除调用哪个方法的歧义.

  • +1这是正确的答案,我很难用这么好的方式来表达它:). (2认同)

xan*_*tos 15

如果您尝试在VB.NET中编译它,您将获得

Sub TestFunc(ByVal val1 As Integer, Optional ByVal val2 As Integer = 0)

End Sub

Sub TestFunc(Optional ByVal val1 As Integer = 0)

End Sub
Run Code Online (Sandbox Code Playgroud)

你会得到 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#更有限.