2

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 编译相同的解决方案,程序就会停止工作。

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

有谁知道,有什么区别?

4

1 回答 1

4

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


作为初步,在规范的 s7.5.3.1(“适用函数成员”)的语言中,两个函数成员都适用(如果另一个不存在,则可以调用它们中的任何一个)以它们的扩展形式(params object[]不能通过string ProductName所以被转换为object参数来实现)。

因此,我们继续讨论 s7.5.3.2(“更好的函数成员”),以确定两者中的哪一个是更好的函数调用。


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

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

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

  • 如果函数成员仅适用于扩展形式,则使用扩展形式。
  • 从参数列表中删除没有对应参数的可选参数
  • 参数被重新排序,以便它们出现在与参数列表中相应参数相同的位置。

这给了我们以下信息:

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

然后,我们进行一系列比较来确定其中哪个是更好的函数成员。调用 oneMp和 one Mq,它们如下所示:

  • 如果Mp是非泛型方法并且Mq是泛型方法,则Mp优于Mq.
    • 这里没有区别
  • 否则,如果Mp以其正常形式适用且Mq具有 params 数组且仅适用于其扩展形式,则Mp优于Mq.
    • 这里没有区别;两者都处于扩展形式
  • 否则,如果Mp声明的参数多于Mq,则Mp优于Mq。如果这两种方法都有params数组并且仅适用于它们的扩展形式,则可能会发生这种情况。
    • 这不是100%。我们的两个参数列表都使用原始函数定义中的 2 个参数。我认为这仅仅是为了区分两个参数进入同一个params数组的一种情况和一个进入数组而一个进入普通参数的情况。
  • 否则,如果 的所有参数Mp都有对应的参数,而默认参数需要替换为至少一个可选参数,MqMp优于Mq.
    • 啊哈!我们的第一个参数列表丢失了optWherePart,它需要一个默认参数,所以第二个参数列表更好!所以VS2015是错的!

... 可是等等。最后一颗子弹是什么意思?Mp并且Mq是特定的参数列表,其中删除了没有相应参数的 [o] 可选参数。他们中的任何一个都不可能没有相应的论点,因为如果他们没有,他们就会被删除。


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

我发现SLaks一篇博文似乎也认为旧行为是一个错误。该博客指出,Roslyn 已通过使编译器失败来解决此问题,而这不再是我所看到的了。也许他们改变了主意?


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

于 2015-08-07T18:41:00.283 回答