Visual Studio 2013和2015之间重载方法行为的变化

时间:2015-08-07 11:57:02

标签: c# visual-studio visual-studio-2013 visual-studio-2015 go-to-definition

Visual Studio 2013和2015有很大问题。在一个类中,我定义了这两种方法:

  1. public List<T> LoadData<T>(string connectionStringName = "", string optWherePart = "", params object[] parameter)
  2. public List<T> LoadData<T>(string optWherePart, params object[] parameter)
  3. 我只想调用第二种方法:

    ....LoadData<Config_Info>("ConfigName LIKE 'Version' AND UserName LIKE '' AND PlugInName Like ?", parameter: ProductName);

    如果我去Visual Studio 2013中定义,我来到第二个方法声明,但在Visual Studio 2015中,我来到第一个。两种解决方案都是 绝对相同。

    即使编译结果也不同,所以如果我用VS 2015编译相同的解决方案,程序就会停止工作。

    这是一种非常奇怪的行为。

    有没有人有想法,有什么区别?

1 个答案:

答案 0 :(得分:4)

这是基于C#5规范,但由于C#6规范似乎尚未发布,但我能做的最好。它也试图援引坎宁安定律。

作为初步,在规范的s7.5.3.1(&#34;适用功能成员&#34;)的语言中,两个功能成员都适用(如果其他人没有&#39,则可以调用它们中的任何一个; t存在)以其扩展形式(params object[] string无法履行ProductName,因此转换为object参数。

因此,我们继续讨论s7.5.3.2(&#34; Better Function Member&#34;),以便决定哪两个是更好的函数。

首先,构造一个精简的参数列表A,它按照它们在原始参数列表中出现的顺序只包含参数表达式

  • { string "ConfigName [...]", string ProductName }

接下来,每个候选函数成员的 [p]参数列表按以下方式构建:

  • 如果功能成员仅适用于展开的表单,则使用展开的表单。
  • 从参数列表中删除没有相应参数的可选参数
  • 重新排序参数,使它们出现在与参数列表中相应参数相同的位置。

这给了我们以下内容:

  • { string connectionStringName, object parameter }optWherePart已删除,params已展开)
  • { string optWherePart, object parameter }params已扩展)

然后我们进行一系列比较,以决定哪些是更好的功能成员。拨打一个Mp和一个Mq,其内容如下:

  • 如果Mp是非通用方法且Mq是通用方法,则Mp优于Mq
    • 此处没有区别
  • 否则,如果Mp适用于其正常格式且Mq具有params数组并且仅适用于其展开形式,那么Mp优于{Mq 1}}。
    • 这里没有区别;两者都处于扩展形式
  • 否则,如果Mp声明的参数多于Mq,则Mp优于Mq。如果两种方法都具有params数组且仅适用于其扩展形式,则会发生这种情况。
    • 这个不是100%。我们的参数列表都使用原始函数定义中的2个参数。我认为这只是 意味着区分一个案例,其中两个参数都进入同一个params数组,一个进入数组,一个进入正常参数。
  • 否则,如果Mp的所有参数都有相应的参数,而默认参数需要替换Mq中的至少一个可选参数,则Mp优于{{} 1}}。
    • 啊哈!我们的第一个参数列表缺少Mq,它需要一个默认参数,所以第二个参数列表更好!所以VS2015错了!

......但等等。这最后一颗子弹甚至意味着什么? optWherePartMp是具体的参数列表,其中 [o] ptional参数没有相应的参数被删除。他们中的任何一个都无法拥有相应的参数,因为如果他们没有,他们就会被删除。

总之,我无法判断这是旧编译器,新编译器......还是C#规范中的错误。

我在blog post找到SLaks,似乎也认为旧的行为是个错误。该博客指出,罗斯林通过使编译器失败来解决这个问题,并且这不再是我所看到的。也许他们改变了主意?

编辑:更新!我的Roslyn bug report生成了change to the compiler,以确保在这种情况下,选择了第二个重载。这似乎是因为默认参数需要替换上面的措辞。我仍然认为规范是模棱两可的,所以我很失望只有代码更改(而不是规范更改,甚至讨论为什么第二次重载更好),但至少VS2015运行时beaviour现在和VS2013一样。