聊聊 C# 方法重载的底层玩法

最近在看 C++ 的方法重载,我就在想 C# 中的重载底层是怎么玩的,很多朋友应该知道 C 是不支持重载的,比如下面的代码就会报错。


#include

int say() {
    return 1;
}
int say(int i) {
    return i;
}

int main()
{
    say(10);
    return 0;
}

聊聊 C# 方法重载的底层玩法

从错误信息看,它说 say 方法已经存在了,尴尬。。。

一:为什么 C 不支持

要想寻找答案,需要了解一点点底层知识,那就是编译器在编译 C 方法时会将 函数名 作为符号添加到 符号表 中,这个 符号表 就是 call 到 say方法字节码 中间的一个载体,画个图大概就是这样。

聊聊 C# 方法重载的底层玩法

简而言之,call 先跳转到 符号表, 然后再 jmp 到 say 方法,问题就出现在这里, 符号表是一种类字典结构,是不可以出现 符号 相同的情况。对了,在 windbg 中我们可以用 x 命令去搜索这些符号,

为了论证我的说法,可以在汇编层面给大家验证下,修改代码如下:


#include

int say(int i) {
    return i;
}

int main()
{
    say(10);
    return 0;
}

接下来再看下汇编。



00C412AD  jmp         say (0C417B0h)


003B2E5F  push        0Ah
003B2E61  lea         ecx,[person]
003B2E64  call        Person::sayhello (03B13A2h)


00007FFB82134E07  mov         rcx,qword ptr [1A8C65E8h]
00007FFB82134E0F  call        Method stub for: ConsoleApp1.Program.Say(System.String) (07FFB81F6F120h)
00007FFB82134E14  nop

从输出信息看,同样也是两个符号表地址,然后由符号表地址 jmp 到最后的方法体。

`c#

00007FFB81F6F118 jmp ConsoleApp1.Program.Say(Int32) (07FFB82134F10h)

Original: https://www.cnblogs.com/huangxincheng/p/16378081.html
Author: 一线码农
Title: 聊聊 C# 方法重载的底层玩法

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/549262/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球