有两个函数具有相同的名称和相同的参数集,但具有不同的返回类型。为什么它不是多态的一种形式,即方法重载?为什么编译器不允许这样做?
答案 0 :(得分:14)
因为C#的设计使得可以从内部到外部分析类型。想象一下,如果你有
int N() {}
float N()() {}
然后打电话
float x = N();
好的,很好,显然我们可以说浮动版本是通缉的。但是你说:
void M(int x) {}
void M(float x) {}
M(N());
好的,现在需要哪个版本?规则是弄清楚N()的含义,然后一旦知道N()意味着,就找出M
的最佳重载是什么。您的理由是从里面到外部。
基于返回类型的重载分辨率需要从外部到内部的推理,并且可能更难以批次。
答案 1 :(得分:3)
请考虑以下事项:
int combine(int a, int b) {
return a + b;
}
float combine(int a, int b) {
return a - b;
}
如果我要调用combine(1,2),编译器就无法知道我想调用哪两种方法(这是不明确的)。
您几乎可以检查返回类型,但是:
var c = combine(1, 2);
dynamic d = combine(1, 2);
combine(1, 2);
在上面,c或d的值应该是多少? 3? -1?这是不可能的。最后一个声明怎么样,没有赋值?我没有定义一个返回void的重载,所以它应该调用哪两个方法?
答案 2 :(得分:2)
避免在呼叫站点出现歧义。请考虑以下界面:
interface ISomething{
int DoSomething()
void DoSomething()
}
现在打电话
myISomething.DoSomething()
哪个应该叫?
答案 3 :(得分:0)
因为不必将返回类型分配给变量。编译器无法强制将返回的值赋给变量。即使它强制执行此操作,停止为float指定整数值也没有意义。如另一个答案所示。
答案 4 :(得分:0)
我相信这可以通过一套复杂的规则(强制执行明确性)来实现,但它会引入许多意外破坏代码的方法。
由于规则将不可避免地复杂化(有点像PHP中的比较运算符),它会带来许多令人困惑的语言怪癖。
值得吗?我们从中获得了什么?问题"为什么不"应该扭转:为什么是的?