我在升级到Visual Studio 2015时发现了同样的问题,所以这不是2017年的新问题,但自2013年以来就是新问题。
我在github上报告了这个问题:
Code that compiles in VS2013 fails with CS0121 in 2015; overloads with different params parameter types #4458:
问题在于代码
是模糊的,新的Roslyn编译器对此比以前的编译器更加严格。
该问题已被关闭,并采取行动改变文档而不是恢复旧的行为,作为问题
Add information about #4458 to "Overload Resolution.md" #4922的一部分。
特别地,
AlekseyTs发表了评论:
所以,新编译器在这方面更加严格,
您需要更改您的代码。鉴于AlekseyTs上面的评论,您
可能需要考虑将此作为其他案例报告给Microsoft的github。如果这种问题现在在2017年变得更加普遍,因为很多人/公司一直在等待升级,如评论所说,他们可能需要重新评估。此外,您在(旧的)文档中找不到任何关于此的内容的原因是,这是旧编译器的“隐藏功能”,正如
他们对文档所做的更改所示: 旧编译器在未使用的参数数组参数存在时实施了特殊的重载解析规则
(不在语言规范中),而Roslyn对规范的更严格解释(现已修复)防止了某些程序的编译。
当我们在代码中解决了相同类型的问题后,最终得到了类似这样的结果(以下是使用您的代码的示例):
public interface IRepository<T> where T : class
{
T Get(object id, Expression<Func<T, object>>[] tieBreaker, params Expression<Func<T, object>>[] includeExprs);
T Get(object id, string tieBreaker, params string[] includeExprs);
}
注意两个
tieBreaker
参数的添加。
然后,我们只需将显式参数与其他参数一起包含在集合中。如果你需要能够调用不带这些可选额外参数的方法,应该添加第三个不带这些参数的重载,以明确应该调用哪个重载,因此你最终的接口可能如下所示:
public interface IRepository<T> where T : class
{
T Get(object id);
T Get(object id, Expression<Func<T, object>>[] tieBreaker, params Expression<Func<T, object>>[] includeExprs);
T Get(object id, string tieBreaker, params string[] includeExprs);
}