问题描述
|
class foo
{
public void bar(int i) { ... };
public void bar(long i) { ... };
}
foo.bar(10);
我希望这段代码会给我一些错误,或者至少是一个警告,但事实并非如此……
调用什么版本的bar(),为什么?
解决方法
正在调用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)
}
}
如示例所示,
始终可以选择方法
明确地将参数转换为
确切的参数类型和/或
显式提供类型参数。
,正如Kevin所说,有一个重载解决程序。该过程的基本草图是:
确定所有可访问的候选方法,可能使用对通用方法的类型推断
过滤掉不适用的方法;也就是说,由于参数不会隐式转换为参数类型而无法使用的方法。
有了一组适用的候选人之后,对他们运行更多过滤器,以确定唯一的最佳候选人。
过滤器非常复杂。例如,最初以较高派生类型声明的方法总是比最初以较少派生类型声明的方法更好。参数类型与参数类型完全匹配的方法要优于不完全匹配的方法。等等。有关详细规则,请参见规范。
在您的特定示例中,“更好”算法很简单。 int与int的精确匹配优于int与long的不精确匹配。
,我会说你是否超过限制
-2,147,483,648 to 2,647
控制权将转至long
范围long
–9,223,372,036,854,775,808 to 9,807
最大值
foo.bar(-2147483648);
要么
foo.bar(2147483648);
如果我们将值超过2147483648,10ѭ将获得控制权