【问题标题】:New VB.NET function signature behavior in Visual Studio 2012/2013Visual Studio 2012/2013 中的新 VB.NET 函数签名行为
【发布时间】:2013-12-12 03:02:30
【问题描述】:

我发现了 VB.NET 如何处理函数签名的一些有趣行为。这种新行为始于 VS2012,并在 VS2013 中持续存在。

考虑以下代码段:

Class test
    Function a(x As String, Optional y As Boolean = False) As String
        Return "function a() was called"
    End Function

    Function a(x As String) As String
        Return "second function a() was called"
    End Function
End Class

我的第一个想法是这不会编译,这在VS2010及更早的版本中都是如此。但是,VS2012 和 VS2013 编译代码时甚至没有警告。如果您随后运行以下命令:

Dim x As New test()
MsgBox(x.a("123"))

消息表明调用了不带可选参数的函数。

有没有办法关闭这种行为?看起来这可能会为开发人员打开大门,让他们在不知不觉中添加与其他具有可选参数的函数同名的函数,从而导致不需要的重定向。

【问题讨论】:

  • 您应该真正放弃使用MsgBox 函数的习惯,该函数仅出于兼容性原因从旧的VB6 代码迁移。 System.Windows.Forms.MessageBox.Show(...) 是要走的路。
  • 正如 David R 在他的回答中提到的,C# 具有相同的行为。因此,如果此更改消除了 VB.NET 和 C# 之间的差异,我认为这是一个很好的更改。
  • 当您提供重载时,该参数不再是可选的。编写合理的代码,所有的部分都会到位。
  • @AndreasAdler 我同意,让 VB.NET 更接近 C# 是一件好事。我仍然会认为它是一个歧义错误,但至少它现在在两种语言之间是统一的。

标签: vb.net visual-studio-2012 overloading visual-studio-2013 optional-parameters


【解决方案1】:

我阅读了 Microsoft 针对 Visual Studio 2013 的 Overload Resolution (Visual Basic) 指南,第 5 步指出:

The compiler considers the remaining overloads in pairs. For each pair, it compares the data types of the defined parameters. If the types in one of the overloads all widen to the corresponding types in the other, the compiler eliminates the latter. That is, it retains the overload that requires the least amount of widening.

本文没有明确说明,但是选择没有可选参数的函数不需要加宽。编译器保留第二个签名,因为它不需要加宽。我无法确定为什么这在 VS2010 和 VS2012 之间发生了变化。

这种行为在类似的CSharp Guide 中明确说明:

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

【讨论】:

    【解决方案2】:

    嗯,我是在看到以下内容后发现这篇文章的,在我看来,异常:

    Class SealedClass
        Public Sub Test(Param1 As String)
            'Some code
        End Sub
        Public Sub Test(Param1 As String, Optional Param2 As String = "")
            'Some other code
        End Sub
    End Class
    
    MustInherit Class BaseClass
        MustOverride Sub Test(ByVal Param1 As String)
        MustOverride Sub Test(ByVal Param1 As String, Optional ByVal Param2 As String = "")
    End Class
    
    Class SubClass
        Inherits BaseClass
        Public Overrides Sub Test(Param1 As String)
            'Some code
        End Sub
        Public Overrides Sub Test(Param1 As String, Optional Param2 As String = "")
            'Some other code
        End Sub
    End Class
    

    在上面的代码中,SealedClass 编译得很好,根据上面的注释。

    然而,尽管BaseClass 编译,SubClass 使BaseClass 中的Sub Test 带有可选参数必须被覆盖。

    对我来说,这是不一致的。有人有意见吗?显然上面的代码只是为了说明;我自己的代码试图通过端口号、身份验证等参数为数据库创建提供重载。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-29
      • 2013-11-03
      • 2015-05-06
      相关资源
      最近更新 更多