Static in C#

ocean
CodxFrankenstein
Published in
5 min readOct 24, 2018

身為一個該死的攻城獅,static 這鬼東西大概會一直不斷的圍繞著你。平常都鴕鳥心態抱著一種反正還可以跑就算了拉~沒想到最近終於被雷到了,TMD該死。花了我四小時找到root cause,於是還是寫一下當作techshare來還債。

文章內容多半不是自己寫的,都是鄉民提供的,小弟僅負責閱讀理解之後整理在這邊,有用到的相關source code或是內容在最下面都附上參考連結,若有任何侵權問題麻煩來信告知。

使用 static 修飾詞來宣告靜態成員,而靜態成員屬於類型本身,而不是特定物件。 static 修飾詞可以與類別、欄位、方法、屬性、運算子、事件和建構函式搭配使用,但不能與索引子、完成項或類別以外的類型搭配使用。 如需詳細資訊,請參閱靜態類別和靜態類別成員

static constructor:

  1. 無法定義存取修飾詞(access modifier) (ex : public, private…)
  2. 只會在類別第一次被初始化時呼叫,而且只會被調用一次
  3. 僅能針對靜態變數(static variable)設定

static variable:

  1. 屬於類別本身的變數,不屬於任何instance,與所有instance共享
  2. 任何instance都可以存取或修改他的值
  3. 一旦修改對於所有屬於該class的instance都會一起變更
  4. 一律透過類別名稱進行存取,而非instance。(ex: ClassA.VariableB)
  5. 無法存取類型中的非靜態欄位和事件,也無法存取任何物件的執行個體變數,除非它明確地傳入方法參數。

static method:

  1. 不需要實例化(instantiate)就可以直接使用的function
  2. 通常用在工具型類別(utility class)
  3. 靜態方法不屬於任何instance,且只能存取類別中的靜態變數
  4. 可以被多載(overload)但不能被複寫(override)
  5. 無法存取類型中的非靜態欄位和事件,也無法存取任何物件的執行個體變數,除非它明確地傳入方法參數。

缺點

  • 無謂地佔住記憶體過久,會一直活在 process memory 中,無法被 gc 回收
  • 直接耦合造成無法獨立進行單元測試
  • 無法享用物件導向設計的好處(繼承的重用與擴充、介面的可抽換性、多型的擴充性)
  • race condition :尤其在 DAO 中將 connection 資源宣告成 static 存放更是一件災難,一旦到線上多人一起使用,就會冒出一堆 connection 佔用/使用中的 exception,更可怕的是往往這種 legacy code 還會把 exception 吃掉,假裝天下太平

範例

從這範例就可以看到兩個instance(DZ跟lin)共用到了Money這個靜態變數,所以導致互相影響,最後DZ的帳戶餘額竟然跟line的相同。所以靜態變數除非是要跨instance共用,否則千萬別亂用。

--

--