Visual Studio 2013和2015有很大问题。在一个类中,我定义了这两种方法:
public List<T> LoadData<T>(string connectionStringName = "", string optWherePart = "", params object[] parameter)
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编译相同的解决方案,程序就会停止工作。
这是一种非常奇怪的行为。
有没有人有想法,有什么区别?
答案 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
数组且仅适用于其扩展形式,则会发生这种情况。
params
数组,一个进入数组,一个进入正常参数。Mp
的所有参数都有相应的参数,而默认参数需要替换Mq
中的至少一个可选参数,则Mp
优于{{} 1}}。
Mq
,它需要一个默认参数,所以第二个参数列表更好!所以VS2015错了! ......但等等。这最后一颗子弹甚至意味着什么? optWherePart
和Mp
是具体的参数列表,其中 [o] ptional参数没有相应的参数被删除。他们中的任何一个都无法拥有相应的参数,因为如果他们没有,他们就会被删除。
总之,我无法判断这是旧编译器,新编译器......还是C#规范中的错误。
我在blog post找到SLaks,似乎也认为旧的行为是个错误。该博客指出,罗斯林通过使编译器失败来解决这个问题,并且这不再是我所看到的。也许他们改变了主意?
编辑:更新!我的Roslyn bug report生成了change to the compiler,以确保在这种情况下,选择了第二个重载。这似乎是因为默认参数需要替换上面的措辞。我仍然认为规范是模棱两可的,所以我很失望只有代码更改(而不是规范更改,甚至讨论为什么第二次重载更好),但至少VS2015运行时beaviour现在和VS2013一样。