Почему переопределение метода связано во время выполнения - PullRequest
4 голосов
/ 02 июня 2011

Overriding - это принцип, который позволяет изменять функциональность метода в дочернем классе.

Например

//Overriding
public class test
{
        public virtual getStuff(int id)
        {
            //Get stuff default location
        }
}

public class test2 : test
{
        public override getStuff(int id)
        {
            //base.getStuff(id);
            //or - Get stuff new location
        }
}

Когда мы Inherit тестируем класс в test2, тогда компилятор знает, что в родительском классе есть виртуальный метод. Тогда почему метод overring ограничен временем выполнения, а не временем компиляции?

Ответы [ 4 ]

3 голосов
/ 02 июня 2011

Это привязка во время выполнения (если это даже правильная формулировка - я не уверен), потому что даже с переменной test2 вы могли бы иметь:

test2 obj = new test3(); // imagine test3 inherits from test2
obj.getStuff(id);

здесь переменная является test2, но объект является test3.Можно утверждать, что, возможно, если бы это было sealed и т. Д., Но на самом деле даже не виртуальные экземпляры (не статические) методы проходят через процесс callvirt.Это работает хорошо и очень быстро.Кроме того, код операции callvirt имеет необходимую нулевую проверку, что означает, что ваш код не должен (под капотом) постоянно проверять наличие нулей (что было бы необходимо, если бы это был статический вызов)

Исключение составляют struct s, которые переопределяют метод object;следующий вызов static :

int i = 1;
string s = i.ToString();
1 голос
/ 02 июня 2011
class BaseClass
{
   public virtual void Test(){
      Console.WriteLine("This is test of base class");
   }
}

class DerivedClass : BaseClass
{
   public override void Test(){
      Console.WriteLine("This is test of derived class");
   }
}

class DerivedClass1 : BaseClass
{
   public override void Test(){
      Console.WriteLine("This is test of derived class-1");
   }
}

сейчас, если вы используете

BaseClass b = new DerivedClass();
b.Test(); // This will derived class method

Предположим, что объект, созданный другим методом, зависит от условия, но все они получены из BaseClass

public BaseClass GetObject(int i)
{
    if(i==1) return new DerivedClass();
    if(i==2) return new DerivedClass1();
}

BaseClass b = GetObject(1);
b.Test(); // This will derivedclass method
BaseClass b = GetObject(2);
b.Test(); // This will derivedclass1 method

Таким образом, все зависит от значения i, которое может быть принято во время выполнения, а во время выполнения зависит от типа ссылки b, удерживаемой в соответствии с этим вызовом метода Test.

1 голос
/ 02 июня 2011

Рассмотрим этот фрагмент.

test Create()
{
    return new test2();
}

test a = Create();
a.getStuff(0); // which method is called?

Компилятор не может знать, что возвращаемое значение метода Create имеет тип test2. Это явно скрыто.

Вы должны посмотреть на это с точки зрения компилятора. Учитывая, что компилятор смотрит на значение, как если бы оно имело тип test, как он мог знать, что вызвать метод test2.getStuff?

0 голосов
/ 02 июня 2011

Просто чтобы добавить к другим ответам, все, что компилятор не может выяснить во время компиляции, он делает это во время выполнения, испуская соответствующий код, который выполняет работу во время выполнения или используя другие методы.

...