C#中Main函數爲何要static

假設沒有static關鍵字,那意味着須要用生成一個實例後才能夠調用這個Main方法,而Main方法是程序入口點,你沒有進入Main方法,天然沒法生成一個實例,既然沒有實例,那就沒法調用Main函數,豈不矛盾?因此Main函數被設置爲static.編程

  Main()函數在C#裏很是特殊,它是編譯器規定的全部可執行程序的入口點。因爲其特殊性,對Main()函數咱們有如下幾條準則:數組

  Main()函數必須封裝在類或結構裏來提供可執行程序的入口點。C#採用了徹底的面向對象的編程方式,C#中不能夠有像C++那樣的全局函數。函數

  Main()函數必須爲靜態函數(static)。這容許C#沒必要建立實例對象便可運行程序。spa

  Main()函數保護級別沒有特殊要求, public,protected,private等均可,但通常咱們都指定其爲public。命令行

  Main()函數名的第一個字母要大寫,不然將不具備入口點的語義。C#是大小寫敏感的語言。對象

  Main()函數的參數只有兩種參數形式:無參數和string 數組表示的命令行參數,即staticblog

  void Main()或static void Main(string[]args) ,後者接受命令行參數。一個C#程序中只能有一個Main()函數入口點。其餘形式的參數不具備入口點語義,C#不推薦經過其餘參數形式重載Main()函數,這會引發編譯警告。繼承

  Main()函數返回值只能爲void(無類型)或int(整數類型)。其餘形式的返回值不具備入口點語義。事件

  在C#中,static變量表示該變量屬於類,而不是類的實例。"static"修飾符聲明一個靜態元素,而該元素屬於類型自己而不是指定的對象,能夠說是該類的全部實例共享一個static變量。開發

  看看什麼是 static class 吧,剛開始我就爲不能聲明一個 abstract sealed class

  而苦惱不已,abstract 和 sealed一塊兒用?定義abstract的目的就是抽象基類,seal表示不能繼承的實體類,徹底是兩回事,怎麼可能一塊兒用呢?abstract代表必需要被繼承,sealed代表不能夠被繼承,這兩個是矛盾的,怎麼能夠一塊兒用呢。

  經過查看 IL 代碼,咱們會發現 static class 實際上就是 abstract sealed class,

  只不過編譯器在編譯時順便對 static class 的成員修飾符進行檢查而已。讓咱們再來猜想一下 MS 開發人員的想法:他們的目的是想得到 abstract sealed class 的效果,但卻爲語義上的矛盾而苦惱不已,你們想得到一個優美的解決方式,因而就爲 C 2.0 新增了一個 static 關鍵字,完美的解決了這個問題。

  也許有人會問:爲何不是 static class = abstract class + static member limit

  而要加上 sealed 的限制呢?理由是繼承一個只有 static 成員的類和從新寫一個類完

  全沒有區別。爲何這麼說呢?由於 static 必然是not virtual,繼承它又能有什麼

  用呢?

  static class 還有一個限制,那就是隻能從 System.Object 繼承,爲何會有這個限

  制,理由和上面差很少。

  往往提到 static 關鍵字,我就想起了 static constructor,感謝 MS 的開發人員提

  供了這麼好的一個特性。可是 C 提供了 static constructor 卻沒有提供static destructor,不過在 Applied Microsoft .NET Framework Programming 一書中

  Jeffery Richter 給咱們提供了一個辦法就是經過 System.AppDomain.DomainUnload

  事件去達到一樣的效果。使用 static constructor 要注意的就是這裏拋出任何異常都會致使該類型在從新加載AppDoamin 以前再也不可用,因此要加倍當心,另外 static contructor 中很容易有兩個類型死鎖的狀況發生,在編寫代碼的時候必定要想清楚。

  const與 readonly的區別 const==static readonly

  const 的概念就是一個包含不能修改的值的變量。

  常數表達式是在編譯時可被徹底計算的表達式。所以不能從一個變量中提取的值來初始化常量。若是 const int a = b+1;b是一個變量,顯然不能再編譯時就計算出結果,因此常量是不能夠用變量來初始化的。

  readonly 容許把一個字段設置成常量,但能夠執行一些運算,能夠肯定它的初始值。

  由於 readonly 是在計算時執行的,固然它能夠用某些變量初始化。

  readonly 是實例成員,因此不一樣的實例能夠有不一樣的常量值,這使readonly更靈活。

  readonly 關鍵字與 const 關鍵字不一樣。

  1. const 字段只能在該字段的聲明中初始化。

  readonly 字段能夠在聲明或構造函數中初始化。所以,根據所使用的構造函數,readonly 字段可能具備不一樣的值。

  2. const 字段是編譯時常數,而 readonly 字段可用於運行時常數。

  3. const 默認就是靜態的,而 readonly 若是設置成靜態的就必須顯示聲明。

  4.const 對於引用類型的常數,可能的值只能是 string 和 null。

  readonly能夠是任何類型

  ----------------------------

  非靜態成員又稱實例成員,必須做用於實例。在程序剛開始運行的時候,未創建任何實例,所以沒法調用實例成員,包括非靜態的Main方法。爲了可以在程序的開始執行Main方法,必須將其聲明爲靜態。

  順便說明,在Main方法中調用的成員也必須是靜態的,除非創建過相應的實例。

  例如:

  namespace lover_P.Test {

  public class Test {

  public void InstanceMethod() {} // 實例成員(非靜態)

  public static void StaticMethod {} // 類型成員(靜態)

  public static void Main() {

  InstanceMethod(); // 錯誤!調用了實例成員,而此時並無創建實例

  StaticMethod(); // 正確!能夠調用靜態成員

  Test SomeTest = new Test(); // 創建本類型的一個實例

  SomeTest.InstanceMethod(); // 再在這個實例上調用實例成員就對了

  SomeTest.StaticMethod(); // 附加一句,在實例上調用靜態成員也是錯誤的!

  }

  }

  }

 原文連接:http://net5x.blog.51cto.com/7900145/1568257%20

相關文章
相關標籤/搜索