#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:
Кажется, я понял.
Я буду динамичным и проанализирован во время выполнения.
Причина в том, что переопределение также является виртуальным методом, поскольку любой, который наследуется от этого класса, также может переопределяться.