一道關於靜態構造函數與抽象類構造函數的面試題引發的思考


前段時間找工作,去面試碰到了兩道關於C#構造函數的題目,首先來看靜態構造函數的題目如下(原題不是如此,但類似,因為實在記不住那題目的樣子了,第二題也是):

    class Base
    {
        static Base()
        {
            Console.WriteLine("Static Base");
        }

        public Base()
        {
            Console.WriteLine("Base");
        }
    } 

問當創建Base的實例時產生什么輸出?我咋一看,挺簡單,我當時認為:構造函數為類的成員,實例化自然是只用到了實例成員,關靜態成員鳥事,什么爛題目。於是寫“Base”。寫歸寫,后來還是有點懷疑(對於不完全確認的程序我還是喜歡自己編碼驗證),於是乎發現真的是我錯了。去new一個類的實例時確實先調用了靜態構造函數(如果存在),那么到底什么時候調用呢,是在聲明的時候(Base b = null;)還是實例化的時候(b = new Base();)調用呢?我覺得是是聲明的時候,然后接着又發現了自己還是錯了。啰嗦有點多了,大家可以上MSDN查看關於靜態構造函數的官方說明:http://msdn.microsoft.com/zh-cn/library/k9x6w0hc(v=vs.80).aspx

接下來我還有一個疑問,就是在繼承關系中這個靜態構造函數的父子類調用情況如何呢?我不敢妄下結論了,老錯。

繼續編寫代碼添加一個子類

    class Child : Base
    {
        static Child()
        {
            Console.WriteLine("Static Child");
        }

        public Child()
        {
            Console.WriteLine("Child");
        }
    }

這時候我去new一個Child對象,輸出如下:

我去,跟實例構造函數的調用順序剛好相反,其所有構造函數的調用順序為:本身靜態構造函數 -> 父類靜態構造函數 -> 父類實例構造函數 -> 本身實例構造函數。

這個東西貌似實用性不是太大,但是在一個含有靜態成員的類里面,還是可以有不少的用武之地的。


 

好,接下來看另一道題,代碼如下

abstract class A
    {
        public A()
        {
            PrintFields();
        }
        public virtual void PrintFields() { }
    }
    class B : A
    {
        int x = 1;
        int y;
        public B()
        {
            y = -1;
        }
        public override void PrintFields()
        {
            Console.WriteLine("x={0},y={1}", x, y);
        }
    }

很常見的一道面試題,熟悉繼承的童鞋一眼就能看出來結果啦,但是我當時碰到兩道一樣的題目,第一道老老實實寫了答案了,然后還有一道是重復的,草泥馬,老子再仔細看下,哦,后面這道是抽象類,我一想抽象類不能實例化,構造函數?也不能有的吧,當時立馬寫下編譯器報錯抽象類不能包含構造函數。后來驗證了,我大錯特錯,抽象類有構造函數且在繼承中其作用情況與非抽象類一樣,OH,this is shit!

哎,丟人丟大了,非常簡單的兩道題目,在此寫下來,覺得有用的拿走吧,覺得沒用的就嘲笑我唄!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM