Почему результат такой?

Не могу понять почему выводится такой результат. Код:

using System;
using System.Collections.Generic;
using System.IO;
namespace ProjectOne {
  public abstract class A{
    public virtual string Print(){
      return "A";
    }
  }
  public class B:A{
    public virtual new string Print(){
      return "B";
    }
  }
  public class C:B{
    public override string Print(){
      return "C";
    }
  }
  class EntryPoint {
    static void Main(string [] args){
    A ac = new C();
    Console.WriteLine (ac.Print());
    }

}}

В классе A метод Print отмечен виртуальным, то есть, его можно переопределить. Но в наследнике B нет переопределения этого метода, а создаётся новый виртуальный метод с тем же именем - ключевое слово new указывает, что создаётся новый метод, не связанный с методом A.Print.

В классе C метод Print переопределяет метод родителя, то есть, метод B.Print, но не переопределяет метод A.Print. Так как у переменной указан тип A, то вызов ac.Print() вызовется метод - единственный из реализаций метода A.Print.

Вот, что б легче было понять:

class A { public virtual void Print() { Console.WriteLine("A"); } }
class B : A { public override void Print() { Console.WriteLine("B"); } }
class C : B { public new virtual void Print() { Console.WriteLine("C"); } }
class D : C { public override void Print() { Console.WriteLine("D"); } }

A ad = new D();
ad.Print(); // покажет B

На курсе C# Essential автор рассматривает эту тему очень подробно, так что рекоммендую просмотреть. А вообще если есть возможность - то в CBS (учебный центр такой, очные курсы) можно пройти этот курс C# Essential (Базовый). Я лично проходил в своё время и мне очень понравилось, так что рекоммендую