为什么虚拟方法被认为是早期约束?

Asp*_*Net 4 c#

绑定的一个定义是它是用内存地址替换函数名的行为.

a)因此我假设早期绑定意味着在编译过程中函数调用被替换为内存地址,而在后期绑定时,这种替换发生在运行时期间?

b)为什么虚方法也被认为是早期绑定(因此在编译时找到目标方法,并创建将调用此方法的代码)?据我所知,使用虚方法只能在运行时解析对实际方法的调用而不是编译时间?!

感谢名单


编辑:

1)

A a=new A();
a.M();
Run Code Online (Sandbox Code Playgroud)

据我所知,在编译时不知道a在运行时将在堆上创建实例(因此在哪个内存地址).现在,通过早期绑定,在编译过程中将函数调用替换为内存地址.但是编译器如何用内存地址替换函数调用,如果它不知道a在运行时将在堆上的哪个对象被创建(这里我假设方法的地址a.M也将在同一个内存位置a)?

2)

v-table调用既不早,也不晚.相反,函数指针表中存在偏移量.偏移量在编译时固定,但是从哪个表中选择函数指针取决于对象的运行时类型(对象包含指向其v表的隐藏指针),因此最终的函数地址在运行时找到.

但假设类型的对象T是通过反射创建的(因此app甚至不知道类型的存在T),那么在编译时如何能够存在该类型对象的入口点?

Jon*_*len 6

后期绑定

使用后期绑定,您拥有的只是方法的名称.在编译时,您无法知道该方法是否存在.这在Ruby或Python等语言中被称为"duck typing".

后期绑定很慢,因为您必须按名称查找函数.它也很危险,因为您没有受到轻微拼写错误的保护.

在版本4之前,除了显式调用反射API之外,C#不支持后期绑定.

早期绑定

使用早期绑定时,您将针对实际方法进行编译.该方法可以直接引用,也可以是V表中的槽.无论哪种方式,你都不会抛出MissingMethod异常.

历史

Visual Basic以支持早期和晚期绑定而闻名,但由于它的其他限制,它从未被视为真正的动态语言.与此同时,7之前的版本(也就是VB.NET)对强制执行早期绑定的支持非常差,因此很难将其称为静态语言.

使用.NET 4,可以说C#和VB都提供静态和动态类型语言所需的大多数功能.

有一次,Java被错误地说具有后期绑定支持,因为事实上它只有早期绑定,OOP风格的V-table.多年来,这引起了很多混乱.