C# 之 結構體詳解

一.結構體的定義

概念:C#的結構體類型(或稱爲結構)是用戶自定義類型的一種, 它爲用戶將實際應用中數據類型不同,但互相聯繫的數據看作 一個整體提供了類型支持。

結構體是值類型的數據類型,可定義在任意命名空間或類中,使用時在其定義域內使用。

定義形式爲:

public struct Student//結構體類型名
{
	 //各種成員...:
	 
	 //成員定義格式爲: 訪問修飾符 成員類型 成員名稱
	 //例:
	 public string name;
	 int age;
}

如果在定義結構體時,某個數據成員之前沒有public訪問修飾符,則結構體類型變量不能訪問這個數據成員。(如上面結構體的age變量是不能被訪問的)

結構體類型的定義是藉助struct關鍵字向編譯器聲明瞭一種新的數據類型;對於該數據類型並沒有分配相應的存儲空間,因此不能直接對結構體中的變量成員進行訪問,賦值等操作;只能在其被實例化之後纔可以對其進行操作。
示例
結構體的成員可以是基礎數據成員,也可以是結構體類型成員(不能是本結構體)。

結構是密封的、不能繼承的。

分配結構比分配類的實例需要更少的消耗,所以對於僅由幾個基礎類型組成的新類型,優先推薦使用結構。


二.結構體的初始化

在定義結構體變量(或者說是實例化結構體)時,系統會根據結構體類型的定義爲其分配相應的存儲空間,此時就可以對結構體中的成員進行賦值,訪問等操作了。

1.實例構造函數

若調用無參數構造進行初始化,則所有變量都會被設置爲該類型的默認值。

結構體預定義的無參構造函數是不允許被重新定義的,並且他會一直存在。
不支持無參構造

定義帶參數的構造函數時,需要將所有字段進行初始化

全部初始化
示例代碼:

class Programma
{
    static void Main(string[] args)
    {
      	Student s1 = new Student();            
        Console.WriteLine(s1.name); //輸出: (空)
        Console.WriteLine(s1.age);  //輸出:0
        s1.name = "CZY";
        s1.age = 11;
        Console.WriteLine(s1.name); //輸出:CZY
        Console.WriteLine(s1.age);  //輸出:11

        Student s2 = new Student("Czhenya", 5);
        Console.WriteLine(s2.name); //輸出:Czhenya
        Console.WriteLine(s2.age);  //輸出:5
	}
	
	struct Student
    {
        public string name;// = "Czhenya";
        public int age;

        public Student(string name,int age)
        {
             this.name = name;
             this.age = age;
        }
     }
}

2.靜態構造函數

靜態構造函數不能有參數
靜態構造必須無參數
靜態構造函數不能有訪問修飾符
靜態構造不支持訪問修飾符
靜態構造函數不能有訪問修飾符,它會在使用帶參構造函數進行初始化時被自動調用訪問靜態數據成員時調用

class Programma
{
    static void Main(string[] args)
    {
    	// 實例化時自動調用靜態函數
      	//Student s3 = new Student("Czhenya", 5); 
       	
       	// 訪問靜態成員時會自動調用	
		//Console.WriteLine(Student.id);
		
		// 給靜態成員賦值時會自動調用
        Student.id = 1;
        Console.WriteLine(Student.id);
	}
	
	struct Student
    {
        public string name;// = "Czhenya";
        public int age;
        public static int id;

        public Student(string name,int age)
        {
             this.name = name;
             this.age = age;
        }
        static Student()
        {
             Console.WriteLine("靜態構造函數被自動調用了...");
        }
     }
}

上面測試代碼註釋全部打開時,可以發現靜態構造只會被調用一次


三.結構體的使用

1.賦值操作

Student s4 = new Student("Czhenya", 5); 
Student s5 = s4;

結構體對象賦值時,本質上是把一個對象內存空間中的全體成員賦值到另一個對象存儲空間中。

如果結構體類型中包括大量的數據成員時,結構體對象的賦值會耗費大量時間,所以一般情況下我們通常情況下不會這樣寫。

2.作爲方法參數和返回值

結構體作爲方法的值參數時將整個結構體深層複製一份到方法的調用空間裏,在方法體內對作爲值參數傳遞進來的結構體進行修改時,不會影響到方法體外作爲實參的結構體。因此,結構體作爲值參數進行傳遞時花銷很大,我們在使用時,通常傳遞多個所需要的參數,而不是將整個結構體傳進去。

class Programma
{
    static void Main(string[] args)
    {
 		Student s6 = new Student("Czhenya", 5);
		Show(s6); 
        Show(s6.name, s6.age);

        Student s7 = Show();
        Console.WriteLine(s7.name);
        Console.WriteLine(s7.age);
    }
    static void Show(Student stu)
    {
        Console.WriteLine("這是使用結構體作爲參數的Show方法:" + stu.name + stu.age);
    }

    static void Show(string name, int age)
    {
        Console.WriteLine("這是多個參數的Show方法..." + name + age);
    }

    static Student Show()
    {
        Console.WriteLine("這是結構體作爲返回值的Show方法...");
        return new Student("Czhenya", 5);
    }

	//還上面代碼中的Student結構體
}

輸出

結構體不僅可以作爲方法的形式參數,也可使用 refout作爲關鍵字當做方法的實際參數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章