2013-03-22 4 views
0

У меня есть следующие классы:Использует ли в программе 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; 
    } 
} 

Главная FUNCTION1:

static void Main(string[] args) 
    { 
     Rectangle rect1 = new Rectangle("Rect1", 3.0f, 4.0f); 
     float Area = rect1.calArea() 
    } 

Главная function2:

static void Main(string[] args) 
    { 
     Polygon poly = new Rectangle("Rect1", 3.0f, 4.0f); 
     float Area = poly.calArea() 
    } 

Я понимаю, что Основная функция 2 использует динамическое связывание.
Если я изменил ключевое слово переопределения на новый в методе calArea класса Rectangle, то это статическая привязка. Как насчет основной функции 1? Использует ли он статическое/динамическое связывание?

ответ

0

Не виртуальный метод - это статическая граница, которая означает, что во время компиляции известно, какой метод вызывать. Предоставляя новое ключевое слово, вы сообщаете компилятору, что это виртуальная/переопределенная область.

Основная функция 1 без определения нового ключевого слова AFAIK будет использовать динамическое связывание, поскольку оно все еще находится в области виртуального переопределения.

+0

Ваш ответ конфликтует с @SergeyS. Я не знаю, кто прав. Какие-либо источники для вашего ответа? – SeeknInspYre

1

Я не думаю, что для динамического связывания это слово «динамическое». Вы говорите о времени компиляции (статического) и времени выполнения. Если класс не унаследован от Rectangle, то в примере 1 для компилятора достаточно информации, чтобы решить, какой метод будет вызываться, и он может выполнять привязку времени компиляции (статического).

[EDIT]:

Видимо, я был не прав. я просмотрел генерируется 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-код нет привязки к реализации точного метода.

+0

Ваш ответ противоречит @Saurabh. Я до сих пор не знаю, кто прав. Какие-либо источники для вашего ответа? – SeeknInspYre

+0

Btw динамическое связывание является правильной терминологией. http://stackoverflow.com/questions/640974/what-is-the-difference-between-static-and-dynamic-binding – SeeknInspYre

+0

Фактически по ссылке вы упомянули очень интересный комментарий @supercat. – SergeyS