【问题标题】:Visual Studio 2010 vs. Visual Studio 2013 - Different Compiler Errors - Why?Visual Studio 2010 与 Visual Studio 2013 - 不同的编译器错误 - 为什么?
【发布时间】:2014-04-24 05:53:00
【问题描述】:

我们发现了一些我们无法解释的奇怪现象。在一个类中,我们有这两个函数:

   Public Overloads Shared Function ToList(ByVal input As Object, _
                                    Optional ByVal StringSeparator As String = ";", _
                                    Optional ByVal CharacterCasing As String = "", _
                                    Optional ByVal StartRow As Integer = 0, _
                                    Optional ByVal EndRow As Integer = -1) As String
            ...
   End Sub

   Public Overloads Shared Function ToList(ByVal Input As Object, _
                            Optional ByVal SplitStringSeparator As String = ",", _
                            Optional ByVal JoinStringSeparator As String = ",", _
                            Optional ByVal PreFixStr As String = "", _
                            Optional ByVal PostFixStr As String = "") As String
           ...
  End Sub

如果我们尝试在 VS2013 中编译这个项目,我们不会收到任何错误。如果我们尝试在 VS 2010 中编译这个完全相同的项目,它会给出以下错误(这是有道理的):

错误 1 ​​'公共共享重载函数 ToList(输入为对象, [StringSeparator As String = ";"], [CharacterCasing As String = ""], [StartRow As Integer = 0]、[EndRow As Integer = -1]) As String' 和 '公共共享重载函数ToList(输入为对象, [SplitStringSeparator As String = ","], [JoinStringSeparator As String = ","], [PreFixStr As String = ""], [PostFixStr As String = ""]) As String' 不能互相重载,因为它们的区别仅在于 可选参数的默认值

错误 2 '公共共享重载函数 ToList(输入为对象, [StringSeparator As String = ";"], [CharacterCasing As String = ""], [StartRow As Integer = 0]、[EndRow As Integer = -1]) As String' 和 '公共共享重载函数ToList(输入为对象, [SplitStringSeparator As String = ","], [JoinStringSeparator As String = ","], [PreFixStr As String = ""], [PostFixStr As String = ""]) As String' 不能互相重载,因为它们的区别仅在于 可选参数的类型。

任何人都很好地解释了为什么在不同版本的 VS 中打开包含 SAME 项目的 SAME 解决方案时有时会出现错误有时不会出现差异?

【问题讨论】:

  • @lll - Roslyn 还没有发布,所以没有......
  • 在 VS2013 中,如果调用不明确,则会在调用者中收到错误。例如,尝试调用 ToList(blah),您会看到以下内容:“重载解析失败,因为没有可访问的 'ToList' 最适合这些参数。”显然,只要您确保每个特定呼叫都明确无误,他们就希望允许这种情况。这仍然不能解释 如何 VS2010 和 VS2013 之间的这种行为会有所不同...
  • @mellamokb 我也刚刚测试过,确认了.. 有趣的是,它似乎违反了spec,“重载类型的成员必须拥有唯一的签名。”和“方法的签名明确地不包括返回类型或参数修饰符,例如 Optional、ByRef 或 ParamArray。”
  • 如果我从 VS2010 解决方案中的命令行手动调用 MSBuild,它构建得很好。所以它似乎是一个只存在于 VS2010 IDE 中的规则,它在 VS2013 中被删除。 编辑: 实际上,这只适用于同时安装了 VS2010 和 VS2013 的机器。在仅安装了 VS2010 的机器上,MSBuild 会生成相同的两个错误。因此,安装 VS2013 似乎包含一个与 VS2010 IDE 的行为不同的更新编译器!
  • @lll - 这意味着他们在自己的开发中使用 Roslyn,而不是 Roslyn 在 VS2013 中.. Roslyn 还没有发布,而且根本不是在 2013 年......跨度>

标签: vb.net visual-studio-2010 visual-studio


【解决方案1】:

查看可通过参考源获得的编译器源代码,我认为我认为它接受第二个函数作为有效重载,因为默认值具有不同的类型。你可以自己看看,vb\language\compiler\symbols\symboltable.cpp, BCSYM::CompareParams() 函数。

    // make sure the types being used for the default are the same
    if ( ParmTypeCompareFlags & ( EQ_Shape | EQ_GenericTypeParams ))
    {
        ComparisonFlags |= EQ_OptionalTypes;

        // don't percolate the difference in the type shape on in this case - the difference we care about it is EQ_OptionalTypes
        ParmTypeCompareFlags &= ~(EQ_Shape | EQ_GenericTypeParams);   // <== Here
    }

关闭EQ_Shape是bug,表示参数不同。我无法将其与 VS2010 中的方式进行比较,该版本不可用。

这当然没有意义。它违反了语言规范第 4.1.1 章的规定:

具有可选参数的方法被认为具有多个签名,每个签名对应于调用者可以传入的每组参数。例如下面的方法有三个对应的签名:

Sub F(x As Short, _
可选 y As Integer = 10, _
可选 z As Long = 20)

这些是方法的签名:
• F(短)
• F(短整型)
• F(短、整数、长)

所以我认为你发现了一个错误。这是一个温和的问题,无论如何都会在呼叫站点解决,您将收到错误 BC30521,“过载解决失败”。您可以在 connect.microsoft.com 上报告它

【讨论】:

  • 感谢您的研究,请随时向 connect.microsoft.com 报告,因为 Hans 应该感谢您解决这一问题。我们刚刚注意到一个奇怪的行为......
猜你喜欢
  • 1970-01-01
  • 2015-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-06
相关资源
最近更新 更多