Может ли переопределенный метод быть подвергнут статическому анализу? - PullRequest
3 голосов
/ 26 октября 2011

Учитывая эту ситуацию:

interface Interfaz 
{
        void M1();
}

abstract class ClaseAbstracta : Interfaz
{
    public void M1() { }
    public abstract Boolean M2();
}

class ClaseConcreta : ClaseAbstracta 
{
    public override Boolean M2() { return false; }
    public virtual void M3(Int32 i) { }
    public void M4() { }
}

Я также делаю:

ClaseConcreta concretaCast = (ClaseConcreta) abst;

Может ли concretaCast.M2() быть проанализирован статически?

Например, он имеет override, поэтому кажется, что не может, но когда вы видите M2(), это фактически конкретная реализация.

Так это статически анализируемый или каждый раз, когда он имеет переопределение, он должен делать это динамически во время выполнения?

Ответы [ 3 ]

2 голосов
/ 27 октября 2011

Я сомневаюсь, что это может быть статически проанализировано в общем случае.Рассмотрим:

class ClaseConcreta2 : ClaseConcreta
{
    public override Boolean M2() { return true; }
}

void Main()
{
    var x = new ClaseConcreta2();
    DoSomething(x);
}

void DoSomething(ClassAbstracta abst)
{
    ClaseConcreta concretaCast = (ClaseConcreta) abst;
    // okay, so it's a ClaseConcreta, but what kind?
}
1 голос
/ 27 октября 2011

Это может иногда быть:

void DoNothingReally(ClaseAbstracta x)
{
  ClaseConcreta y = new ClaseConcreta();
  y.M2(); // Only possibly the implementation from ClaseConcreta.
  ClaseAbstracta abst = y;
  ClaseConcreta concretaCast = (ClaseConcreta) abst;
  concretaCast.M2(); // Only possibly the implemenation from ClaseConcreta, but more work to figure this out.
  x.M2(); // can't know where the implentation is from generally, but see below
}
void DoMoreNothing()
{
  DoNothingReally(new ClaseConcreta());//the call x.M2() above will only possibly the implemenation from ClaseConcreta but lots of work to figure that out.
}

Теперь еще один вопрос: определит ли это что-нибудь на самом деле ? В статье о C ++ Бьярн Страуструп говорит о том, что компиляторы могут заменить виртуальные вызовы не виртуальными вызовами в качестве оптимизации. Я понятия не имею, как много это делается в C ++, не берите в голову, если что-то делает с C #. Хотя теоретически это возможно.

0 голосов
/ 27 октября 2011

Я думаю, что понял.

Я буду динамичен и проанализирован во время выполнения.

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

...