Использует ли следующая программа на C# статическое или динамическое связывание?
У меня есть следующие классы:
class Polygon
{
protected string name;
protected float width, height;
public Polygon(string theName, float theWidth, float theHeight)
{
name = theName;
width = theWidth;
height = theHeight;
}
public virtual float calArea()
{
return 0;
}
}
class Rectangle : Polygon
{
public Rectangle(String name, float width, float height) : base(name,width,height)
{
}
public override float calArea()
{
return width * height;
}
}
Основная функция1:
static void Main(string[] args)
{
Rectangle rect1 = new Rectangle("Rect1", 3.0f, 4.0f);
float Area = rect1.calArea()
}
Основная функция2:
static void Main(string[] args)
{
Polygon poly = new Rectangle("Rect1", 3.0f, 4.0f);
float Area = poly.calArea()
}
Я понимаю, что основная функция 2 использует динамическое связывание.
Если я изменю ключевое слово переопределения на новое в методе calArea класса Rectangle, то это статическая привязка. Как насчет основной функции 1? Использует ли оно статическое / динамическое связывание?
2 ответа
Я не думаю, что "динамическое" связывание - правильное слово для этого. Вы говорите о компиляции (статической) и привязке во время выполнения. Если ни один класс не унаследован от Rectangle - тогда в примере 1 для компилятора достаточно информации, чтобы решить, какой метод будет вызван, и он может выполнить (статическую) привязку во время компиляции.
[РЕДАКТИРОВАТЬ]:
Видимо я был не прав. Я проверил сгенерированный код IL для примера 1 и примера 2 с "новым" вместо "переопределить", и код основной функции выглядит так же:
IL_000f: newobj instance void Console.Program/Rectangle::.ctor(string,
float32,
float32)
IL_0014: stloc.0
IL_0015: ldloc.0
IL_0016: callvirt instance float32 Console.Program/Polygon::calArea()
Из этого кода мы видим, что даже для Примера 1 - метод callArea вызывается из класса Polygon. Таким образом, на этапе компиляции в код IL нет привязки к точной реализации метода.
Не виртуальный метод - это статическая привязка, что означает, что во время компиляции известно, какой метод вызывать. Предоставляя новое ключевое слово, вы сообщаете компилятору, что это виртуальная область / область переопределения.
Основная функция 1 без определения нового ключевого слова, AFAIK будет использовать динамическое связывание, поскольку оно все еще находится в области действия для виртуального переопределения.