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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...