繁体   English   中英

选择看起来像错误/缺失功能的重载时,奇怪的C#编译器行为

[英]Strange C# compiler behavior when choosing overload that looks like a bug/missing feature

我最近发现了一个有趣的C#编译器行为。 想象一下这样的界面:

public interface ILogger
{
   void Info(string operation, string details = null);
   void Info(string operation, object details = null);
}

如果我们这样做

logger.Info("Create")

编译器会抱怨他不知道选择哪个重载(不明确的调用......)。 似乎合乎逻辑,但是当你尝试这样做时:

logger.Info("Create", null)

它突然没有麻烦,搞清楚null是一个字符串。 此外,似乎找到正确的重载的行为已经随着时间的推移而改变,我发现旧代码中的错误在之前工作并且停止工作,因为编译器决定使用另一个重载。

所以我真的很想知道为什么C#在第二种情况下不会像第一种情况那样产生相同的错误。 这样做似乎非常符合逻辑,但它尝试将其解析为随机重载。

PS我不认为提供这种模糊的界面是好的,不建议这样做,但遗产是遗留的,必须保持:)

在C#6中引入了一个突破性的变化,使得重载分辨率更好。 这是功能列表:

改善了重载分辨率

重载决策有许多小的改进,这可能会导致更多的东西按照你期望的方式工作。 这些改进都与“更好”有关 - 编译器决定哪两个重载对于给定参数更好。

您可能会注意到这一点(或者更确切地说是停止注意问题!)的一个地方是在选择采用可空值类型的重载时。 另一种方法是将方法组(而不是lambdas)传递给期望委托的重载。 细节不值得在这里扩展 - 只是想让你知道!


但它会尝试并将其解析为随机过载。

不,C#不会随机选择重载,这种情况是模糊的调用错误。 C#选择更好的方法。 请参阅C#规范中的7.5.3.2更好的函数成员一节:

7.5.3.2更好的功能成员

否则,如果MP具有比MQ 更多的特定参数类型,则MP优于MQ。 设{R1,R2,...,RN}和{S1,S2,...,SN}表示MP和MQ的未实例化和未展开的参数类型。 MP的参数类型比MQ更具体,如果对于每个参数,RX的特定性不低于SX,并且对于至少一个参数,RX比SX更具体:

鉴于stringobject更具体,并且在nullstring之间存在隐式转换,那么神秘就解决了。

暂无
暂无

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

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