【发布时间】:2011-09-01 19:21:31
【问题描述】:
class foo
{
public void bar(int i) { ... };
public void bar(long i) { ... };
}
foo.bar(10);
我希望这段代码会给我一些错误,或者至少是一个警告,但不是这样......
什么版本的 bar() 被调用,为什么?
【问题讨论】:
标签: c# methods resolution
class foo
{
public void bar(int i) { ... };
public void bar(long i) { ... };
}
foo.bar(10);
我希望这段代码会给我一些错误,或者至少是一个警告,但不是这样......
什么版本的 bar() 被调用,为什么?
【问题讨论】:
标签: c# methods resolution
正在调用 bar 的 int 版本,因为 10 是一个 int 字面量,编译器将寻找与输入变量最匹配的方法。要调用长版本,您需要指定一个长文本,如下所示:foo.bar(10L);
这里是 Eric Lippert 的一篇关于更复杂的方法重载版本的帖子。我会尝试解释它,但他做得更好,我可以做到:http://blogs.msdn.com/b/ericlippert/archive/2006/04/05/odious-ambiguous-overloads-part-one.aspx
来自 C# 4.0 规范:
方法重载允许多个 同一类中的方法具有 相同的名称,只要它们具有唯一性 签名。当编译一个 调用重载方法, 编译器使用重载决议 确定具体方法 调用。重载解析发现 一种最匹配的方法 如果没有参数或报告错误 可以找到单个最佳匹配。这 以下示例显示重载 决议生效。评论为 Main 方法中的每次调用 显示实际上是哪种方法 调用。
class Test {
static void F() {
Console.WriteLine("F()");
}
static void F(object x) {
Console.WriteLine("F(object)");
}
static void F(int x) {
Console.WriteLine("F(int)");
}
static void F(double x) {
Console.WriteLine("F(double)");
}
static void F<T>(T x) {
Console.WriteLine("F<T>(T)");
}
static void F(double x, double y) {
Console.WriteLine("F(double,double)");
}
static void Main() {
F(); // Invokes F()
F(1); // Invokes F(int)
F(1.0); // Invokes F(double)
F("abc"); // Invokes F(object)
F((double)1); // Invokes F(double)
F((object)1); // Invokes F(object)
F<int>(1); // Invokes F<T>(T)
F(1, 1); // Invokes F(double, double)
}
}
如示例所示,一个特定的 方法总是可以选择 将参数显式转换为 确切的参数类型和/或 显式提供类型参数。
【讨论】:
我会说如果你超出限制
-2,147,483,648 to 2,147,483,647
控制权将转到long
long 的范围
–9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
int 的最大值
foo.bar(-2147483648);
或
foo.bar(2147483648);
如果我们超过该值 2147483648,Long 将获得控制权
【讨论】:
正如凯文所说,有一个过载解决流程。该过程的基本草图是:
过滤器相当复杂。例如,最初在派生程度较高的类型中声明的方法总是比最初在派生程度较低的类型中声明的方法好。参数类型与参数类型完全匹配的方法比不完全匹配的方法要好。等等。具体规则见规范。
在您的特定示例中,“更好”算法很简单。 int 与 int 的精确匹配优于 int 与 long 的不精确匹配。
【讨论】: