当我在C#中发生早期/晚期绑定时,我正试图解决这个问题.
非虚方法总是早期绑定.虚方法总是后期绑定:编译器插入额外的代码来解析在执行时绑定到的实际方法并检查类型安全性.因此,子类型多态性使用后期绑定.
使用反射调用方法是后期绑定的一个示例.我们编写代码来实现这一点,而不是编译器.(例如,调用COM组件.)
当Option Strict关闭时,VB.NET支持隐式后期绑定.当对象被赋值为声明为Object类型的变量时,该对象是后期绑定的.VB编译器在执行时插入代码以绑定到正确的方法并捕获无效的调用.C#不支持此功能.
我正朝着正确的方向前进吗?
如何调用委托并通过接口引用调用方法?是早期还是晚期绑定?
Sco*_*ham 98
除非您通过Reflection接口,否则一切都在C#中提前绑定.
早期绑定意味着在编译时找到目标方法,并创建将调用此代码的代码.无论是虚拟还是非虚拟(意味着在呼叫时有一个额外的步骤可以找到它是无关紧要的).如果该方法不存在,编译器将无法编译代码.
后期绑定意味着在运行时查找目标方法.通常使用方法的文本名称来查找它.如果方法不存在,那就砰的一声.程序将在运行时崩溃或进入某个异常处理方案.
大多数脚本语言使用后期绑定,编译语言使用早期绑定.
C#(版本4之前)没有后期绑定; 但是,他们可以使用反射API来完成它.该API编译为通过在运行时挖掘程序集来查找函数名称的代码.如果关闭Option Strict,VB可以延迟绑定.
绑定通常会影响性能.因为后期绑定需要在运行时进行查找,所以通常意味着方法调用比早期绑定方法调用慢.
对于普通函数,编译器可以在内存中计算出它的数字位置.然后在调用函数时,它可以生成一个指令来调用该地址的函数.
对于具有任何虚方法的对象,编译器将生成v表.这本质上是一个包含虚方法地址的数组.具有虚方法的每个对象都将包含由编译器生成的隐藏成员,该成员是v表的地址.当调用虚函数时,编译器将计算v表中适当方法的位置.然后它将生成代码以查看对象v-table并在此位置调用虚方法.
因此,虚函数会发生查找.这是经过大量优化的,因此在运行时会很快发生.
早期约束
后期绑定
Joe*_*son 17
C#3使用早期绑定.
C#4使用dynamic关键字添加后期绑定.有关详细信息,请参阅Chris Burrow关于此主题的博客文章.
至于虚拟方法和非虚方法,这是一个不同的问题.如果我调用string.ToString(),C#代码绑定到虚object.ToString()方法.调用者的代码不会根据对象的类型而改变.相反,通过函数指针表调用虚方法.对象的实例是指对象的表,指向它的ToString()方法.string的一个实例有它的虚方法表指向它的ToString()方法.是的,这是多态性.但它不是迟到的约束力.
小智 5
在大多数情况下,早期绑定是我们每天所做的事情.例如,如果我们Employee在编译时有一个类,我们只需创建该类的实例并调用任何实例成员.这是早期约束.
//Early Binding
**Employee** employeeObject = new **Employee**();
employeeObject.CalculateSalary();
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您在编译时没有该类的知识,那么唯一的方法是使用反射进行后期绑定.我遇到了一个很好的视频来解释这些概念 - 这是链接.
| 归档时间: |
|
| 查看次数: |
92261 次 |
| 最近记录: |