OverLoad就是重载,大家都会。但是大家有没有想过,我们调用一个重载方法的时候会调用哪个呢??
答案是和签名最接近的一个。 大家是不是看到这里已经开始觉得这个博客很无聊了,都是这么简单的内容。没关系,我们慢慢深入。
我们知道方法为了能够减少书写个数, 提供了一个叫默认参数的东西
void P(object p1, bool p2 = true)
{
}
这样我们可以通过P(p1)
或者P(p1true)
两种方式来进行调用
如果我们这个时候的重载情况时这样的
void P(object p1)
{
Console.WriteLine("第一个");
}
void P(object p1,bool p2 = true)
{
Console.WriteLine("第二个");
}
此时再调用,P(p1)
执行的是上一个函数。一种理解方式是,第二个方法比第一个能够多处理一种情况P(p1,true)
。所以我们专事专用,选择更具体的方法。
ok.C#作为一个OO语言,还有一个特点就是继承,这个同样反映在方法里
void P(object p1)
{
}
对于上述方法,可以使用object
作为参数,也可以使用更加具体的object
子类 那么如果我们的重载情况时这样的
void P(object p1)
{
Console.WriteLine("第一个");
}
void P(exception p1)
{
Console.WriteLine("第二个");
}
那么如果我们传入的参数是exception
或者是exception
的子类,那么执行第二个,如果是exception
的父类或者其他object
的派生类,则执行的是第一个函数 同样的思路,如果运行P(new Exception())
时第二个函数,更加具体或者说更加”专业”
那么重点来了,在如下的条件下,执行P(null)
,输出时什么?
void P(object p1)
{
Console.WriteLine("第一个");
}
void P(exception p1,bool p2 = true)
{
Console.WriteLine("第二个");
}
不知道了是吧,那我们换成P(new Exception())
。第一反应是不是应该输出”第二个”。没错,微软也是这么做的。我们这么想,p2
涉及的状态只有有和无两种。而继承涉及的状态多如牛毛 所以在函数签名匹配时继承高于默认参数 那么我们回来看P(null)
的输出 恩,是不是还是啥都不知道。没错这边涉及null
应该是更加具体,还是更加抽象。 其实我也不知道,于是就做了demo测试,结果是输出”第二个” 所以我们从现象反推,我们可以这么想null
可以为所有object
对象赋值,所null
更具体
OK,那我们需要输出”第一个”是咋办咧,可以使用强转P((object)null)
不过目前我这边没有找到任何确定文档表明这一个特性,所以有可能是编译器未定义的行为,所以不建议大家随意使用
本文会经常更新,请阅读原文: https://xinyuehtx.github.io/post/%E7%A5%9E%E5%A5%87%E7%9A%84Overload.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名黄腾霄(包含链接: https://xinyuehtx.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 。