繁体   English   中英

C# 6 中方法重载解析的重大变化 - 解释?

[英]Breaking change in method overload resolution in C# 6 - explanation?

我们公司最近从 VS2013 迁移到了 VS2017。 升级后,我们的代码库将不再构建。 我们会得到以下错误:

以下方法或属性之间的调用不明确:'IRepository<T>.Get(object, params Expression<Func<T, object>>[])' 和 'IRepository<T>.Get(object, params string[] )'

这是调用本身:

this.mainRepository.Get(newEntity.Id);

...和接口定义:

public interface IRepository<T> where T : class
{
    T Get(object id, params Expression<Func<T, object>>[] includeExprs);
    T Get(object id, params string[] includeExprs);
}

我想知道这里是否有人可以解释为什么会这样。 我怀疑 C# 6.0 的新改进方法重载解析功能,但查看语言规范我无法找出导致该问题的确切规则。

编辑

我写了一篇关于这个问题的后续博客文章: http : //codewithstyle.info/method-overload-resolution-in-c-6-0-an-interesting-bug-story

我在升级到 Visual Studio 2015 时发现了同样的事情,所以这不是 2017 年的新东西,而是 2013 年以来的新东西。

我在github上报告了它:

在 VS2013 中编译的代码在 2015 年以 CS0121 失败; 具有不同 params 参数类型的重载 #4458

问题是,该代码模糊的和新的罗斯林编译器在这方面比以前的编译器更严格。

该问题已通过更改文档而不是恢复到旧行为的操作结束,作为问题的一部分将有关 #4458 的信息添加到 "Overload Resolution.md" #4922

特别是, AlekseyTs评论了这一点:

为了我们的重载解析代码的未来健康,我们决定保留破坏(和正确)行为。 如果我们得到的不仅仅是这个单一案例,我们可能需要重新评估。

所以你有它。 新编译器对此更加严格,您需要更改代码

鉴于 AlekseyTs 的上述评论,您可能需要考虑在 github 上将此作为额外的此类案例报告给 Microsoft。 如果这种问题在 2017 年结束后变得更加普遍,因为很多人/公司已经等待升级,正如评论所说他们可能想要重新评估。

此外,您在(较旧的)文档中找不到任何有关此内容的原因是,这是较旧编译器的“隐藏功能”,从他们对文档所做更改中可以明显看出:

旧的编译器在存在未使用的 param-array 参数的情况下实现了重载解析的特殊规则(不在语言规范中) ,而 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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM