C#早期和晚期绑定概念

C#早期和晚期绑定概念,c#,binding,C#,Binding,众所周知,早期绑定的概念是声明特定数据类型的对象,它不能保存任何其他类型的对象。而后期绑定的概念是声明泛型类型的对象,它可以保存任何其他类型的实例。 考虑这个例子: public abstract class Animal { public virtual string Name { get { return "Animal"; } } } public class Dog : Animal { public override string Name { get { ret

众所周知,早期绑定的概念是声明特定数据类型的对象,它不能保存任何其他类型的对象。而后期绑定的概念是声明泛型类型的对象,它可以保存任何其他类型的实例。 考虑这个例子:

public abstract class Animal  
{ 
 public virtual string Name { get { return "Animal"; } } 
} 

public class Dog : Animal 
{ 
  public override string Name { get { return "Dog"; } } 
} 

public class Cat : Animal 
{ 
  public override string Name { get { return "Cat"; } } 
} 

public class Test  
{ 
  static void Main() 
  {
      Animal animal = new Dog(); 
      Animal animalTwo = new Cat(); 

      Console.WriteLine(animal.Name); 
      Console.WriteLine(animalTwo.Name); 
   } 
} 
我的问题是编译器什么时候能识别对象的函数调用,要么是在编译时,要么是在运行时? 如果我不清楚,我很抱歉。 但我想问的是,虚拟优先权和虚拟方法的概念是否涉及后期绑定。。如果没有,那么这怎么可能。

运行时

虚拟函数意味着调度在运行时路由到活动对象引用上的函数。在C++中,这是通过一个称为VTABLE的指针表完成的。我不确定C#是如何实现的,我假设它依赖于实现,但结果是一样的


在编译时,编译器将函数调用绑定到基类上的函数。该基类函数是虚拟的,因此在运行时.Net将查看实际的对象类型,并查看它是否覆盖该函数。如果这样做,将调用派生类型。

是的,虚拟方法涉及后期绑定


要了解更多关于绑定的信息,以及是什么原因导致了绑定的延迟,请阅读以下帖子:

Gaz:If If i write Cat c=new Cat();并将函数调用为c.Name();那么它在编译时会被识别吗?一个虚拟函数在整个层次结构中都是虚拟的,所以c.Name仍然会涉及某种类型的查找,以防派生类型重写它(例如BlackCat)。您的意思是虚拟调度是延迟绑定的一种形式,即如果函数定义为虚拟,那么对该函数的任何调用都将在运行时被识别???否。延迟绑定和动态调度是两种不同的东西。虚拟函数在编译时(早期)绑定,但在运行时调度。C#的后期绑定需要使用反射。在纪尧姆:C#需要后期绑定??我只在stackoverflow上读到,除了动态和反射接口之外,所有东西都是在c#中进行早期绑定的。下面是链接:[link]“虚拟调度是后期绑定的一种形式”-Eric Lippert,c#编译器团队的主要开发人员。