C#基类构造器调用虚方法

今天又翻出了Don Box的《Essential .Net》,又看到了当初曾经反复琢磨的虚方法分派的问题。在.net中,如果基类的构造器中调用了一个虚方法,它并不是直接调用基类中的虚方法,而是在子类中不存在override版本的时候才调用基类的虚方法,如果子类中有override版,那么就调用子类的方法。可以看个小例子,感觉下这种调用方式

public class Fruit

    {

        public Fruit()

        {

            WriteFruitName();

        }

        public virtual void WriteFruitName()

        {

            Console.WriteLine("Fruit's WriteFruitName()");

        }

    }

    public class Banana : Fruit

    {

        public override void WriteFruitName()

        {

            Console.WriteLine("Banana's WriteFruitName()");

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Banana b = new Banana();

            Console.ReadLine();

        }

    }

}

此方法执行后的结果是:Banana's WriteFruitName();因为Banana继承自Fruit,所以new Banana()首先调用基类的构造方法Fruit(),但是在基类构造方法内又调用了虚方法WriteFruitName,当程序执行到此次时,会在Banana的方法表中查找是否有方法WriteFruitNameoverride版,如果有则调用,没有就调用基类的虚方法。

下面看个略微深入点示例,道理都一样的,在方法中增加一名称属性,

public class Fruit

    {

        public Fruit()

        {

            FruitName = "Fruit";

            WriteFruitName();

        }

        public virtual void WriteFruitName()

        {

            Console.WriteLine("Fruit's WriteFruitName(),The Name Is " + FruitName);

        }

        protected string FruitName{ get; set; }

    }

    public class Banana : Fruit

    {

        public Banana()

        {

            FruitName = "Banana";

        }

        public override void WriteFruitName()

        {

            Console.WriteLine("Banana's WriteFruitName(),The Name Is " + FruitName);

        }

    }

    class Program

    {

        static void Main(string[] args)

        {

            Banana b = new Banana();

            Console.ReadLine();

        }

    }

这次方法的执行结果是:Banana's WriteFruitName(),The Name Is Fruit。原因就是调用虚方法时,发现子类覆载了该方法,所以调用Banana类的WriteFruitName,但此时Banana类的构造器还没被执行,也就是说FruitName属性在Banana类中还没被赋值呢,而基类的构造器给它赋值为Fruit。这种方式仅供欣赏,实际生产中基本不这样用。

posted @ 2011-08-15 07:50  秋无语  阅读(981)  评论(1编辑  收藏  举报