Использует ли следующая программа на 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 будет использовать динамическое связывание, поскольку оно все еще находится в области действия для виртуального переопределения.

Другие вопросы по тегам