visual studio 2013年至2015年间过载方法行为的变化



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)

我只想这样调用第二种方法:

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

如果我在Visual Studio 2013中进行定义,那么我会得到第二个方法声明,但在Visual Studio 2015中,我会得到第一个方法声明。两种解决方案都是完全相同。

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

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

有人知道吗,有什么不同?

这是基于C#5规范的,但由于C#6规范似乎还没有发布,这是我能做的最好的事情。这也是调用Cunningham定律的一种尝试。


初步而言,在规范的s7.5.3.1("适用函数成员"(的语言中,两个函数成员都以其扩展形式适用(如果另一个不存在,则可以调用其中一个((params object[]不能由string ProductName实现,因此转换为object参数(。

因此,我们转到s7.5.3.2("Better Function Member"(,以决定调用这两个函数中的哪一个更好。


首先,构造了一个精简的参数列表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
    • 这里没有区别;两者都是展开形式
  • 否则,如果Mp具有比Mq更多的声明参数,则MpMq更好。如果这两种方法都有params数组,并且仅适用于它们的扩展形式,则可能发生这种情况
    • 这不是100%。我们的两个参数列表都使用了原始函数定义中的2个参数。我认为这只是用于区分两个参数进入同一params数组的一种情况,以及一个进入数组和一个进入正常参数的情况
  • 否则,如果Mp的所有参数都有相应的参数,而默认参数需要替换Mq中的至少一个可选参数,则MpMq更好
    • 啊哈!我们的第一个参数列表缺少optWherePart,它需要一个默认参数,所以第二个参数列表更好!所以VS2015是错误的

但是等一下。最后一颗子弹是什么意思?MpMq是特定的参数列表,其中删除了没有相应参数的可选参数。他们中的任何一个都不可能有相应的参数,因为如果没有,他们就会被删除。


总之,我不知道这是旧编译器的错误,还是新编译器的错误。。。或者C#规范。

我发现SLaks的一篇博客文章似乎也认为这种旧行为是一个错误。博客上说Roslyn已经通过使编译器失败来解决了这个问题,我现在已经看不到了。也许他们改变了主意?


编辑:更新!我的Roslyn错误报告导致对编译器进行了更改,以确保在这种情况下,选择第二个重载。这似乎是因为默认参数需要替换上面的措辞。我仍然认为规范是模糊的,所以我很失望只做了一个代码更改(而不是规范更改,甚至没有讨论为什么第二个重载是更好的(,但至少VS2015运行时beaviour现在与VS2013中相同。

相关内容

  • 没有找到相关文章

最新更新