Можно ли статически проанализировать переопределенный метод?

#c# #oop #static-analysis

#c# #ооп #статический анализ

Вопрос:

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

 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() , что это на самом деле конкретная реализация.

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

Комментарии:

1. Статическая анимализация: недопустима в 26 состояниях.

2. Может быть, он фанат KISS ^^

3. @Trufa: почему вы думаете, что этого не должно быть?

4. Действительно, люди 🙂 языки написаны с использованием синтаксиса, подобного английскому, пожалуйста, используйте английский!!! Чтение чего-то вроде «interface Interfaz» или «class GestoreTicketOspedalieri» сводит меня с ума!

5. @SalvatorePreviti да, это не мой код, это пример кода из моего университета. Мне было лень переводить … извините: =

Ответ №1:

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

 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. Я не совсем уверен, в чем ваша точка зрения, var x будет ClaseConcreta2() , и вы сможете передать его в качестве параметра из-за приведения. Но я не совсем уверен, что вы пытаетесь мне показать … извините:(

2. @Trufa: Мой пример — это еще один способ сказать то, что вы сказали в своем ответе.

3. Хм, думаю, теперь я понял. 1. Спасибо за ответ, хороший пример, я продолжу читать и, возможно, приму его позже. Спасибо!

Ответ №2:

Иногда это может быть:

 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 #. Хотя теоретически это возможно.

Ответ №3:

Кажется, я понял.

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

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