【问题标题】:Overloaded method selection logic重载的方法选择逻辑
【发布时间】:2013-09-25 17:51:45
【问题描述】:

给定以下重载方法:

public string Test(long item)
{
    return "Test with a long was called!";
}

public string Test(int item)
{
    return "Test with an int was called!";
}

public string Test(object item)
{
    return "Test with an object was called!";
}

当我打电话给Test(),传递一个short,像这样:

short shortValue = 7;
var result = Test(shortValue);

为什么result 的值等于"Test with an int was called!",而不是"Test with an object was called!"

【问题讨论】:

    标签: c# overloading


    【解决方案1】:

    为什么值结果等于“Test with an int was called!”,而不是“Test with an object was called!”?

    int 的转换比到object 的转换“更好”,因此采用int 的重载比采用object 的重载“更好” - 两者都适用,因为short 是隐含的可转换为intobject。 (采用long的重载也可以,但是转换成int也比转换成long好。)

    有关一般重载规则,请参阅 C# 语言规范的第 7.5.3 节,有关“更好的转换”的规则,请参阅第 7.5.3.3 节。将它们全部写在这里没有什么意义,因为它们很长 - 但最重要的方面是有从 intobject 的转换,但没有从 objectint 的转换 - 所以转换到int 更具体,因此更好。

    (节号来自C#4和C#5版本。您可以下载Word格式的C# 5 spec。)

    【讨论】:

    • +1 - 啊,认为它更喜欢继承而不是转换。很高兴知道,感谢 C# 规范的链接。
    【解决方案2】:

    C# 规范规则意味着编译器更喜欢将short 转换为int,而不是object。我认为这是由于 7.5.3.5 Better conversion target 的以下规则(链接是 C# 5 规范下载,或在线查看 equivalent from C# 1.2

    鉴于 T1 和 T2 两种不同的类型,如果至少满足以下条件之一,T1 是比 T2 更好的转化目标:

    • 存在从 T1 到 T2 的隐式转换,不存在从 T2 到 T1 的隐式转换
    • T1 是有符号整数类型,T2 是无符号整数类型。 [其他内容省略]

    要针对这种情况重写它,由于存在从intobject 的隐式转换,并且不存在从objectint 的隐式转换,因此转换为int 是更好的转换。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-13
      • 2013-10-18
      • 2012-04-09
      相关资源
      最近更新 更多