다음과 같이 작동합니다. 다음과 같이
Animal animal;
Dog dog;
animal = new Human();
animal.Eat();
animal = new Animal();
animal.Eat();
dog = new Dog();
dog.Eat();
animal = dog;
animal.Eat();
컴파일러 이유 :
class VTable
{
public VTable(Func<Animal, string> eat)
{
this.AnimalEat = eat;
}
public readonly Func<Animal, string> AnimalEat;
}
class Animal
{
private static AnimalVTable = new VTable(Animal.AnimalEat);
private static string AnimalEat(Animal _this)
{
return "undefined";
}
public VTable VTable;
public static Animal CreateAnimal()
{
return new Animal()
{ VTable = AnimalVTable };
}
}
class Human : Animal
{
private static HumanVTable = new VTable(Human.HumanEat);
private static string HumanEat(Animal _this)
{
return "human";
}
public static Human CreateHuman()
{
return new Human()
{ VTable = HumanVTable };
}
}
class Dog : Animal
{
public static string DogEat(Dog _this) { return "dog"; }
public static Dog CreateDog()
{
return new Dog()
{ VTable = AnimalVTable } ;
}
}
지금 이러한 호출을 고려 수신기의 종류가해야 먹을 호출이 다음 동물 인 경우 상상 컴파일러는 이것으로 클래스를 다시 썼다 동물. 동물. 동물. 수신자의 유형이 Dog이면 호출은 DogEat이어야합니다. 그래서 컴파일러가 기록이 같은 : 어떻게 작동하는지 정확히입니다
Animal animal;
Dog dog;
animal = Human.CreateHuman(); // sets the VTable field to HumanVTable
animal.VTable.AnimalEat(animal); // calls HumanVTable.AnimalEat
animal = Animal.CreateAnimal(); // sets the VTable field to AnimalVTable
animal.VTable.AnimalEat(animal); // calls AnimalVTable.AnimalEat
dog = Dog.CreateDog(); // sets the VTable field to AnimalVTable
Dog.DogEat(dog); // calls DogEat, obviously
animal = dog;
animal.VTable.AnimalEat(animal); // calls AnimalVTable.AnimalEat
. 컴파일러는 백그라운드에서 vtable을 생성하고 은 오버로드 해결 규칙의 규칙에 따라 vtable을 통해 호출할지 여부를 컴파일 타임에 결정합니다.
vtable은 객체가 생성 될 때 메모리 할당자가 설정합니다. 합니다 (VTABLE이되지 후, 전에의 ctor를 호출 설정되어 있기 때문에 내 스케치는이 점에서 거짓말이다.)
은 "이"가상의 방법은 실제로 비밀리에 보이지 않는 형식 매개 변수로 전달의 방법.
의미가 있습니까?
에릭 리 퍼트 (Eric Lippert)가이 주제에 대한 블로그 시리즈를 쓰고 있음을 알고 있습니까? http://blogs.msdn.com/b/ericlippert/archive/2011/03/17/implementing-the-virtual-method-pattern-in-c-part-one.aspx – Learner
Learner에게 감사드립니다. 나는 그것을 따라 간다. – Nishant