關於C#中靜態的一點認識

来源:https://www.cnblogs.com/green-jcx/archive/2020/06/26/13194853.html
-Advertisement-
Play Games

1.靜態直觀的特點 靜態成員最顯著的一個特點就是它的作用域是全局的。只要在調用處引入了對應的命名空間,那麼我們可以在代碼任何地方都可以直接使用。凡是具有全局特征的東西我們就可以考慮使用靜態。在實際的開發中,靜態欄位我們常用實現數據的共用,修飾為靜態的方法當做常用的工具方法來使用。 2.命名上的思考 ...


1.靜態直觀的特點

  靜態成員最顯著的一個特點就是它的作用域是全局的。只要在調用處引入了對應的命名空間,那麼我們可以在代碼任何地方都可以直接使用。凡是具有全局特征的東西我們就可以考慮使用靜態。在實際的開發中,靜態欄位我們常用實現數據的共用,修飾為靜態的方法當做常用的工具方法來使用。

 

2.命名上的思考

  靜態從名稱的對立面上可以想到一個詞叫動態,這裡所說的動態可以隱喻為實例成員。實例成員之所以可以形容為動態因為在記憶體中它的創建和釋放資源是根據實例化對象或GC(垃圾回收)不斷變化的。而靜態成員在記憶體中很少會發生變化,靜態成員的創建是在第一次訪問對應的類型時進行的創建,資源釋放是在應用程式結束的時候。

 

3.靜態和實例(非靜態)的對比

靜態

實例(非靜態)

需要static關鍵字

不需要static關鍵字

無法實例化只能使用類名調用

必須實例化對象後才能調用

在靜態方法中,可以訪問靜態成員

在實例方法中,可以訪問靜態成員

在靜態方法中不可以直接訪問實例成員,如需訪問需要創建對象

在實例方法中,可以直接訪問實例成員

調用前初始化(在創建第一個實例或引用任何靜態成員之前)

實例化(調用構造函數)對象時初始化

 

4.靜態成員的初始化的創建過程(本文重點)

當一個類當中包含了靜態成員時,程式內部是如何初始化靜態成員的呢?

4.1代碼示例說明1

 如運行上圖的程式,對於這種情況實際上即使是在程式運行時該類中的靜態成員是沒有被創建(初始化的)。之所以是這種情況,因為程式中靜態成員對應的類型並沒有在任何位置出現過訪問該類型的代碼。而靜態成員的創建是在第一次訪問這個類型時創建的。

 

4.2代碼示例說明2

   在遵循靜態成員的創建原則後,此圖對代碼進行改動後包含了對類型的訪問,那麼這個時候靜態成員是會被創建的。

  從直觀的代碼上來看,很顯然會產生一個對靜態成員初始化的誤解,因為代碼中的靜態成員在聲明時已經進行初始化賦值的操作。其實這種方式只是一種語法糖,是為了方便程式員給的簡單語法。實際上對於類型內部的欄位賦值是通過構造函數來完成的。

  我們現在思考一個問題:上圖代碼中並沒有編寫任何的構造函數,那麼靜態成員是如何進行初始化賦值的呢?

  通過一般的調試時並看不出程式內部的執行過程,也很難找尋問題的答案。此處為了探尋上述的問題我可以通過反編譯工具查看下上圖中反編譯後的代碼。如圖:

   上圖中我們可以看到通過反編譯後MyClass內部包含了一個靜態的構造函數並且為靜態成員進行賦值。此處可以得到一個結論:當在類中定義靜態成員的時候,實際上也定義了一個靜態構造函數。

  

  根據反編譯代碼的情況我們將靜態構造函數顯示的寫在代碼中調試,來驗證下靜態構造函數是否被調用,然後觀察下實例成員和靜態成員初始化的順序。如圖:

  

   根據上圖中的演示可以看出靜態構造函數被調用,並且會先調用靜態構造函數然後在調用實例構造函數。

 

5.關於靜態構造函數需要註意強調的幾點

  1. 靜態構造函數的定義上:不能有訪問修飾符並且必須無參,一個類或結構當中只能有一個構造函數,不允許重載和繼承。
  2. 靜態構造函數調用上:靜態構造函數在編寫代碼時不能像實例構造函數那樣直接調用,它的調用是由公共語言運行時(CLR)調用。並且靜態構造函數只會調用一次。

以下代碼運行圖驗證靜態構造函數只會調用一次的情況:

 

使用建議:

  儘量少使用靜態成員,因為靜態成員的生命周期是在應用程式結束後釋放的,然而GC(垃圾回收)沒有對其進行記憶體的回收管理。促使會上時間的占用記憶體,並且會產生一些記憶體垃圾。

學習感想:

   看似使用簡單的靜態特性,有人運用設計出了軟體模式的單例模式。淬煉堅實的基本功永遠都不算晚,個人覺得編程最難的是在運用,就算學會在高端的技術如果不會組合運用,也還是沒有達到真正掌握的程度。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、整體說明 tomcat需要完成兩件事情: 接受外部HTTP請求 載入servlet,並且把請求傳給Servlet進行處理。 整體可以抽象為如下: 二、整體代碼架構 在tomcat的代碼中抽象了以下三個類: Server類,代表tomcat實例 Connector類,代表HTTP監聽器(上圖中的H ...
  • 本篇文章分享看題目就知道是寫給初學者的,學的比較好的小伙伴也可以將自動演算法等一些知識給加進去,希望對大家有幫助! 好了,當我們所有的準備工作做好之後,我們就可以來編寫我們的C語言連連看游戲了! 其實這個游戲設計起來真的是很簡單的一種,本例用到的知識點主要有:數組,結構體,分支結構,圖形庫函數。 游戲 ...
  • a=['序號',1,2,3,4,5] b=['成本',20,45,12,34,67] import pandas c=pandas.Series(a) d=pandas.Series(b) e=pandas.DataFrame(list(zip(c,d))) print(e) 0 1 0 序號 成本 ...
  • HTTP 非同步風格伺服器 # http_server.php $http = new Swoole\Http\Server("0.0.0.0", 9501); // 設置伺服器運行參數 $serv->set(array( 'daemonize' => 1, // 作為守護進程運行,需同時設置log_ ...
  • 【一、項目目標】 通過Python爬取QQ音樂數據(一)我們實現了獲取 QQ 音樂指定歌手單曲排行指定頁數的歌曲的歌名、專輯名、播放鏈接。 此次我們在之前的基礎上獲取QQ音樂指定歌曲的歌詞及前15個精彩評論。 【二、需要的庫】 主要涉及的庫有:requests、json、html 【三、項目實現】 ...
  • 使用原始django,太過於笨重和雜多nginx是一個輕量級的web伺服器,在處理靜態資源和高併發有優勢uwsgi是一個基於python的高效率的協議,處理後端和動態網頁有優勢所以這裡採用靜態網頁交給nginx解析,動態網頁交給uwsgi解析,並且nginx配置ssl,即可以使用出高安全,高效率的部 ...
  • C# 實現TXT文檔轉 代碼: public DataTable TXTToDataTable(string fileName, string columnName) { DataTable dt = new DataTable(); FileStream fs = new FileStream(f ...
  • C#類型名稱 說明 取值 .NET框架類型 預設值 sbyte 8位有符號整數 -128~127 System.SByte 0 byte 8位無符號整數 0~255 System.Byte 0 short 16位有符號整數 -32768~32767 System.Int16 0 ushort 16位 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...