这个问题再次引起了我的兴趣.有人可以提供技术解释,说明为什么以下代码不会产生任何警告或错误.你必须问自己的问题(当然)你感到幸运吗?
class Program
{
static string Feeling(object o) { return "Lucky"; }
static string Feeling(string s) { return "Unlucky"; }
static void Main(string[] args)
{
Console.WriteLine("I feel " + Feeling(null));
}
}
Run Code Online (Sandbox Code Playgroud)
如果您知道在不运行代码的情况下将调用哪种方法,则会获得奖励积分.只是为了添加侮辱,它不仅仅发生在null参数:
class Program
{
static string Feeling(int i) { return "Lucky"; }
static string Feeling(uint i) { return "Unlucky"; }
static void Main(string[] args)
{
Console.WriteLine("I feel " + Feeling(7));
}
}
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,它将调用string过载.null匹配两者object和string,但字符串是更具体/派生的类型.因此它选择string.
检查Eric Lippert的帖子方法重载决策系统如何决定在传递空值时调用哪个方法?对于这部分重载分辨率的更长解释.
现在我们必须确定最适合的候选人.最佳规则是复杂的,但简短版本是更具体的优于不太具体的.
在第二种情况下,它将选择第一个重载,因为文字7是int.如果你曾经使用7u它,那么uint第二次过载将是首选.
整数文字具有定义良好的类型(即使它们允许比正常的整数值更多的隐式转换).您可以使用类似于uunsigned的后缀,或者l长时间来影响该类型.或者您可以添加显式强制转换.
虽然通常int不会隐式转换为uint,但这是一个整数常量,它在有效范围内uint,并且C#编译器有一个额外的规则允许整数常量之间的隐式转换,前提是常量适合目标的范围.
Eric再次解释了细节:为什么从int到uint的隐式转换有效?
如果constant-expression的值在目标类型的范围内,则int类型的常量表达式可以转换为sbyte,byte,short,ushort,uint或ulong类型.如果常量表达式的值不是负数,则long类型的常量表达式可以转换为ulong类型.
在两个示例中,就C#编译器而言,一个重载显然是最好的,因此您不会出现模糊的重载错误.
我个人认为第一个例子应该发出警告,但是C#团队不同意,或者他们根本没有时间添加启发式.
| 归档时间: |
|
| 查看次数: |
2252 次 |
| 最近记录: |