程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 解析關於實例化順序的C#面試題

解析關於實例化順序的C#面試題

編輯:C#入門知識

題目如下:
  public class BaseA
  {
  public static MyTest a1 = new MyTest("a1");
  public MyTest a2 = new MyTest("a2");
  static BaseA()
  {
  MyTest a3 = new MyTest("a3");
  }
  public BaseA()
  {
  MyTest a4 = new MyTest("a4");
  }
  public virtual void MyFun()
  {
  MyTest a5 = new MyTest("a5");
  }
  }
  public class BaseB : BaseA
  {
  public static MyTest b1 = new MyTest("b1");
  public MyTest b2 = new MyTest("b2");
  static BaseB()
  {
  MyTest b3 = new MyTest("b3");
  }
  public BaseB()
  {
  MyTest b4 = new MyTest("b4");
  }
  public new void MyFun()
  {
  MyTest b5 = new MyTest("b5");
  }
  }
  static class Program
  {
  static void Main()
  {
  BaseB baseb = new BaseB();
  baseb.MyFun();
  }
  }
  public class MyTest
  {
  public MyTest(string info)
  {
  Console.WriteLine(info);
  }
  }
  最後的問題是:請寫出Main()方法中,a1-a5,b1-b5這十個類實例化的順序。(MyTest類是我自己添的,方便查看結果,原題是是實例化一個object類。)
  不知道園子裡有多少人能胸有成竹的寫出正確答案,反正我是答錯了,正確答案是:
  b1
  b3
  b2
  a1
  a3
  a2
  a4
  b4
  b5
  題目中涉及到的知識點
  雖然題目沒做對了,但要知道自己為什麼會做錯,這樣才會有所提高,趁著端午的假期,我把這個面試題涉及到的知識點都梳理了一遍,要點如下:
  內聯(inline)方式初始化字段。
  類型構造器(靜態構造函數)的執行時間。
  C#中基類和子類實例化的順序。
  new修飾符的作用。
  內聯方式初始化字段
  這個知識點在《CLR via C#》書中有講到,所謂內聯方式,就是初始化字段的一種簡化語法。來看示例代碼:
  public class SomeType
  {
  public int m_x = 5;
  }
  這種在類中聲明變量時進行賦值的方式就叫做內聯,大致等效於下面的代碼:
  public class SomeType
  {
  public int m_x;
  public SomeType()
  {
  m_x = 5;
  }
  }
  之所以說“大致等效”,因為兩者的執行順序上略有差異,編譯器會首先生成內聯方式的代碼,然後再調用構造函數。
  比如,下面的代碼,最後m_x的結果就為10。
  public class SomeType
  {
  //先執行
  public int m_x=5;
  public SomeType()
  {
  //後執行
  m_x = 10;
  }
  }
  類型構造器的執行
  所謂類型構造器也就是我們熟知的靜態構造方法,在我們編寫的類中,都會有一個默認的靜態無參構造方法,跟無參實例構造方法一樣是默認存在的。
  每當我們對一個類創建第一個實例或訪問靜態字段前,JIT編譯器就會調用該類的靜態構造方法。當然,靜態變量也可以使用上面說的內聯方法進行賦值。
  這裡可以看出,當第一次實例化某個類時,會首先調用該類的靜態構造方法。
  C#中基類和子類實例化的順序
  這個知識點比較簡單,那就是在調用子類實例構造方法之前會調用基類的實例構造方法。從面試題的結果可以看出,基類的構造方法又比子類的靜態構造函數晚一些,此處因個人能力有限,我也沒辦法從更底層的角度去分析原理,只能暫且記住吧。
  new修飾符的作用
  我看過不少關於new以修飾符的形式用在方法聲明中的題目,關於new的用法在MSDN上也都查的到,官方說法是“顯式隱藏從基類繼承的成員”。
  我個人的理解比較簡單:當子類中,一個方法的簽名(指參數,方法名,返回值)與基類的一個方法相同,通過加入new修飾符,可以讓子類不做更改的去使用該方法。
  說到底,new修飾符就是讓兩個不相關的同名方法同時存在而已。(這裡同名指相同的方法簽名)
  最後
  回頭想想,其實在我日常的項目開發中,多多少少都有涉及到這幾個問題,只是平時不注意,沒有深究吃透,寫此文也是勉勵自己以後要重視基礎,不再浮躁。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved