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 ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系