c#核心基礎--類的構造方法

来源:http://www.cnblogs.com/liyongke/archive/2017/01/20/6323744.html
-Advertisement-
Play Games

一、構造方法 類的構造方法是類的成員方法的一種,它的作用是對類中的成員進行初始化操作。類的構造方法分為: 1.靜態構造方法 2.實例構造方法 1.靜態構造方法 類的靜態構造方法是類的成員方法的一種,它的作用是對類中的靜態成員進行初始化操作。下麵請看代碼實例: 1 using System; 2 na ...


一、構造方法

  類的構造方法是類的成員方法的一種,它的作用是對類中的成員進行初始化操作。類的構造方法分為:

    1.靜態構造方法
    2.實例構造方法

  1.靜態構造方法

  類的靜態構造方法是類的成員方法的一種,它的作用是對類中的靜態成員進行初始化操作。下麵請看代碼實例:

 1 using System;
 2 namespace LycheeTest {
 3     class Test {
 4         //定義一個靜態成員變數
 5         private static int a;
 6         //定義靜態構造函數
 7         static Test() {
 8             //初始化靜態成員變數
 9             a = 11;
10         }
11         public void Show() {
12             Console.WriteLine("靜態欄位 a 的值是:{0}", a);
13             
14         }
15     }
16     class Program {
17         static void Main(string[] args) {
18             Test t = new Test();
19             t.Show();
20             Console.ReadKey();
21         }
22     }
23 }       

   首先,上面這段代碼定義了兩個類。第 3 行代碼定義了類 Test。定義類的時候,類的訪問許可權修飾符有兩個,一個是 public,另一個是 internal。當不寫任何訪問修飾符的時候,類的訪問許可權預設是 internal。 這個訪問許可權的意義是,這個類只能被本程式集訪問,不能被本程式集以外的類訪問。如果這個類是屬於類庫的,那麼它必須是 public 的,否則調用它的程式集就不能訪問它。第 5 行代碼定義了一個靜態欄位成員,第 7 行代碼就是靜態構造方法。可以看到,靜態構造方法的特點是,以 static 關鍵字說明這個方法是靜態的,方法名稱要和類名完全相同,這裡要註意大小寫。靜態構造方法不能含有參數,靜態構造方法不能有返回值。在靜態構造方法體內可以做初始化靜態成員的操作。第 11 行代碼定義了一個實例方法,它的作用是輸出靜態欄位的值。在第 16 行的類 Program 中的 Main(註意:在java中是main) 方法中調用了這個類,第 18行創建了這個類的一個實例,第 19 行 調用了類的實例方法。

  從上面的代碼中可以看到,並沒有顯式調用類的靜態構造方法。

  下麵請看以上代碼的執行結果:

 靜態欄位 a 的值是:11  

  可以看到,靜態構造方法確實是被執行了。那麼上例就是靜態構造方法的執行條件之一,在類的實例被創建時,類的靜態構造方法將被自動調用。

  靜態構造方法的調用次序是在靜態欄位的初始值設定項之後。

  也就是第一步是靜態欄位的預設值設置,第二步是執行靜態欄位的初始值設定項,第三步就是調用類的靜態構造方法。

  下麵將前面的代碼實例修改一下,代碼如下:

 1 using System;
 2 namespace LycheeTest{
 3     class Test {
 4         private static int a;
 5         static Test() {
 6             a++;
 7         }
 8         public void Show() {
 9             Console.WriteLine("靜態欄位 a 的值是:{0}", a);
10             14
11         }
12     }
13     class Program {
14         static void Main(string[] args) {
15             Test t = new Test();
16             t.Show();
17             Test t1 = new Test();
18             t.Show();
19             Console.ReadKey();
20         }
21     }
22 }

  這段代碼將靜態構造方法做了修改,在方法體內將靜態欄位 a 進行自增操作。然後在代碼的第 17 行又 創建了一個類的實例,然後再次調用類的實例方法。

  下麵看執行結果:

靜態欄位 a 的值是:1 
靜態欄位 a 的值是:1

  可以看到,靜態欄位的值並沒有增加。這就是靜態構造方法執行的特點,它只執行了一次。當程式集 運行的時候,將會創建一個應用程式域,在一個應用程式域中,類的靜態構造方法僅僅執行一次。

  下麵再對代碼實例進行修改如下:

 1 using System;
 2 namespace LycheeTest {
 3     class Test {
 4         public static int a;
 5         static Test() {
 6             Console.WriteLine("類的靜態構造方法開始執行");
 7             a++;
 8         }
 9         public void Show() {
10             Console.WriteLine("靜態欄位 a 的值是:{0}", a);
11         }
12     }
13     class Program {
14         static void Main(string[] args) {
15             Console.WriteLine("靜態欄位 a 的值是:{0}", Test.a);
16             Console.WriteLine("靜態欄位 a 的值是:{0}", Test.a);
17             Console.ReadKey();
18         }
19     }
20 }

  這段代碼在類的靜態構造方法中列印輸出了一行標記,類的靜態欄位的訪問許可權也修改為 public,這讓它可以在類外被調用。在 Main 方法中兩次列印輸出了靜態欄位的值,註意在類外調用類的靜態欄位需要 使用類名進行引用。

  下麵是代碼的執行結果:

類的靜態構造方法開始執行 
靜態欄位 a 的值是:1 
靜態欄位 a 的值是:1

  本段代碼並沒有創建類的實例。在引用類的靜態成員之前,類的靜態構造方法將被調用。這個被調用的類的靜態成員包括靜態欄位和靜態方法。這就是類的靜態構造方法調用的第二個條件。

  下麵再對代碼實例進行修改如下: 

 1 using System;
 2 namespace LycheeTest {
 3     class Program {
 4         private static int a;
 5         static Program() {
 6             Console.WriteLine("類的靜態構造方法被調用");
 7             a = 11;
 8         }
 9         static void Main(string[] args) {
10             Console.WriteLine("Main 方法被調用");
11             Console.WriteLine("靜態欄位 a 的值是:{0}", a);
12             Console.ReadKey();
13         }
14     }
15 }

   這段代碼在包含 Main 方法的類中定義了靜態欄位和靜態構造方法。因為 Main 方法也是一個靜態方法,類的靜態構造方法被調用而且它是類的入口點方法,那麼它和類的靜態構造方法之間是誰先調用呢?下麵首先來看代碼的執行結果:

類的靜態構造方法被調用
Main 方法被調用 
靜態欄位 a 的值是:11

  通過代碼的執行結果可以看到,因為類的入口點方法仍然是一個靜態方法,那麼在任何靜態成員被調用之 前,靜態構造方法都首先被調用。所以,可以得出如下結論,類的靜態構造方法先於類的 Main 方法被調用。

  那麼類的靜態構造方法能否被顯式調用呢?下麵看代碼實例:

 1 using System;
 2 namespace LycheeTest {
 3     class Program {
 4         private static int a;
 5         static Program() {
 6             Console.WriteLine("類的靜態構造方法被調用");
 7             a = 11;
 8         }
 9         static void Main(string[] args) {
10             Program();
11             Console.ReadKey();
12         }
13     }
14 }

  在這段代碼中的第 10 行顯式調用了類的靜態構造方法,這時編譯器會報錯。

  2.實例構造函數

  類的實例構造方法是類的成員方法的一種,它的作用是對類的實例成員進行初始化操作。實例構造方法可以實現重載,在創建類的實例時,可以顯式的指定不同的參數來調用重載的不同的實例構造方法。下麵請看代碼實例:

 1 using System;
 2 namespace LycheeTest {
 3     class Program {
 4         private static int a;
 5         private int b = 12;
 6         private string c = "Hello World";
 7 
 8         static Program() {
 9             Console.WriteLine("類的靜態構造方法被調用");
10             a = 11;
11         }
12         public Program(int a, string s) {
13             Console.WriteLine("帶二個參數的構造方法被調用");
14             this.b = a;
15             this.c = s;
16         }
17         public Program(int a) : this(a, "通過 this 關鍵字調用構造方法") {
18             Console.WriteLine("帶一個參數的構造方法被調用");
19         }
20         public void Show() {
21             Console.WriteLine("靜態欄位 a 的值是:{0}", a);
22             Console.WriteLine("實例欄位 b 的值是:{0}", b);
23             Console.WriteLine("實例欄位 c 的值是:{0}", c);
24         }
25         static void Main(string[] args) {
26             Program p1 = new Program(33, "這是創建的實例 P1");
27             Program p2 = new Program(34);
28             p1.Show();
29             p2.Show();
30             Console.ReadKey();
31         }
32     }

  這段代碼的第 4 行、第 5 行和第 6 行分別定義了三個欄位成員,第 4 行是靜態欄位,第 5 行和第 6 行代碼都有初始值設定項。代碼的第 8 行就是一個實例構造方法的定義,實例構造方法也是以類名作為方法名,它沒有返回值, 在方法名前面是訪問許可權修飾符,可以使用的訪問許可權修飾符包括 public、private 和 protected。其中的 protected 意味著構造方法只能在此類內部訪問。實例構造方法可以帶參數。 第 12 行代碼的實例構造方法使用兩個傳入的參數對實例欄位進行了賦值。第 17 行代碼定義了帶一個參數的實例構造方法,它和前一個實例構造方法形成了重載。實例構造方法可以通過 this 關鍵字調用其他的實例構造方法,方法就是在參數列表的後面使用冒號然後接 this 關鍵字, 然後再跟參數列表,這個參數列表要匹配另一個重載的實例構造方法。第 17 行的構造方法只有一個參數, 它將這個參數通過 this 關鍵字傳遞給了另一個構造方法,在用 this 調用另一個構造方法的時候,為其同時傳入了一個字元串參數。第 24 行的實例方法列印類的欄位成員的值。在 Main 方法中,第 26 行代碼和第 27 行代碼分別定義了兩個實例,它們使用 new 關鍵字調用了不同的實例構造方法。第 28 行和第 29 行分別調用實例方法列印類的靜態欄位和實例的兩個欄位成員的值。

  下麵先來看代碼的執行結果:

類的靜態構造方法被調用 帶二個參數的構造方法被調用 帶二個參數的構造方法被調用 帶一個參數的構造方法被調用 
靜態欄位 a 的值是:11
實例欄位 b 的值是:33 實例欄位 c 的值是:這是創建的實例 P1 靜態欄位 a 的值是:11 實例欄位 b 的值是:34 實例欄位 c 的值是:通過 this 關鍵字調用構造方法

  現在用執行結果來介紹實例構造方法的執行過程,當第 26 行代碼創建類的實例時,類的靜態欄位首先被設置成預設值,因為沒有欄位的初始值設定項,所以接著就執行類的靜態構造方法。這時靜態欄位 a 被 設置成 11。因為第 26 行代碼使用 new 調用了帶有兩個參數的實例構造方法,所以首先實例欄位 b 被設置為 0,實例欄位 c 被設置為 null。然後執行欄位的初始值設定項,b 被賦值為 12,c 被賦值為“Hello World”。接 下來執行實例構造方法體中的第一個語句,“帶二個參數的構造方法被調用”這個字元串被列印。接下來 實例 p1 的欄位 b 被設置為傳入的參數 33,註意構造方法的形參 a 在這裡覆蓋了類的靜態欄位 a。也就是說, 這時起作用的是實例構造方法的局部變數 a。然後實例欄位 c 被設置為字元串"這是創建的實例 P1"。第 27 行代碼使用 new 關鍵字調用了帶一個參數的實例構造方法,在調用時,首先屬於 p2 的實例欄位 b 被設置為 0,實例欄位 c 被設置為 null。然後執行欄位的初始值設定項,b 被賦值為 12,c 被賦值為“Hello World”。接下來執行的是 this 引用的帶兩個參數的實例構造方法,"帶二個參數的構造方法被調用"這個 字元串被列印。然後 b 被設置為 34,c 被設置為"通過 this 關鍵字調用構造方法"。最後,代碼控制又返回 來執行帶一個參數的實例構造方法體中的列印語句,"帶一個參數的構造方法被調用"這個字元串被列印。 至此,實例構造方法的執行完畢。接下來的代碼列印靜態欄位的值,可以看到兩個實例列印出來的靜態欄位值是一樣的,但是它們的實 例欄位的值各不相同。

  可選參數和命名參數也可以用於實例構造方法,下麵看代碼實例:

 1 using System;
 2 namespace LycheeTest {
 3     class Program {
 4         private int b;
 5         private string c;
 6         public Program(int a = 12, string s = "") {
 7             this.b = a;
 8             this.c = s;
 9         }
10         public void Show() {
11             Console.WriteLine("實例欄位 b 的值是:{0}", b);
12             Console.WriteLine("實例欄位 c 的值是:{0}", c);
13         }
14         static void Main(string[] args) {
15             Program p1 = new Program(); //構造方法的兩個參數都採用預設值
16             Program p2 = new Program(34); //構造方法的 string 類型參數採用預設值
17             Program p3 = new Program(23, "Hello World"); //構造方法的兩個參數採用傳入參數
18             Program p4 = new Program(s: "今天的天氣真好"); //採用命名參數,另一個參數 a 採用預設值
19             p1.Show();
20             p2.Show();
21             p3.Show();
22             p4.Show();
23             Console.ReadKey();
24         }
25     }
26 }

  代碼的第 6 行定義了一個帶有可選參數和命名參數的構造方法,然後第 15 創建了一個類的實例,在構造方法中沒有傳入任何參數,這時,構造方法的兩個參數都採用預設值。第 16 行代碼為構造方法傳入了一個 int 類型的參數,這時,另一個 string 類型的參數採用預設值。 第 17 行代碼傳入了兩個參數,構造方法的兩個參數都使用了這兩個傳入的參數。第 18 行代碼使用了命名參數指定傳入的參數是 string 類型的參數,並將它傳遞給形參 s。這時另一 個 int 類型的參數採用預設值。第 19 行到第 23 行代碼列印類的實例欄位的值。這段代碼的執行結果如下

 

實例欄位 b 的值是:12 
實例欄位 c 的值是: 
實例欄位 b 的值是:34 
實例欄位 c 的值是: 
實例欄位 b 的值是:23
實例欄位 c 的值是:Hello World 實例欄位 b 的值是:12
實例欄位 c 的值是:今天的天氣真好

 

 

 

 

 


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

-Advertisement-
Play Games
更多相關文章
  • 這裡採用的是.net的一個引用NReco.Recommender.dll,這是一個國外電影網站推薦系統衍生而來的,有興趣的可以到他們的官網看看。 以圖書商城為例 MVC 構造行為數據 首先需要對資料庫進行設計,增加一張用戶的行為數據表,記錄用戶訪問網站的行為,例如商城的一般記錄瀏覽的商品和購買過的商 ...
  • 根據以前的做法是拼接sql語句,這會增加維護成本,因為sql語句里的內容不會報錯,所以在使用ef的時候必須要拋棄拼接sql語句的習慣。 構建實例 構建搜索條件 參數過濾 很多情況下查詢到的結果並不能滿足我們的需要,還需要進行一些處理,這裡需要用linq ...
  • 網站的後臺,多數是需要使用datatable來展示數據的,因為datatable的功能比較強大,可以更好的使用。 引用css html代碼 js代碼 服務端代碼 ...
  • 現在的.NET Core 1.0版本是一個很小的核心,APIs和工具也並不完整,但是隨著.Net Core的不斷完善,補充的Apis和創新也會一起整合到.NET Framework中。 安裝centos系統 請自行安裝或百度教程 安裝 libicu包 和 dotnet 溫馨提示:如果需要用vsc編輯 ...
  • 方法里包括了圖片大小限制、圖片尺寸、文件內容等等的判斷。。。 該案例是mvc下的demo,支持單張圖片上傳。 一般處理程式 csharp public void ProcessRequest(HttpContext context) { context.Response.ContentType = ...
  • 關於C#調用廣州醫保HG_Interface.dll調用的一些總結(外部組件異常) ...
  • 在SuperSocket入門(二)中我們已經簡單瞭解了通過配置App.config文件使用BootStrap啟動SuperSocket服務。我們先來看一下上個案例中的基本配置文件示例: <?xml version="1.0" encoding="utf-8"?> <configuration> <c ...
  • 這個問題說起來,我有點慚愧 想當初在大學里學的就是ASP.NET WebForms 在實習期間也是用的WebForms來開髮網站,然後就覺得.NET開髮網站就是用這個開發模式 現在想想都想笑。。。實在忍不住了,我要笑了。哈哈哈!!! 好,回到正題 ASP.NET 是一個使用 HTML、CSS、Jav ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...