C#中的結構
在C#中用關鍵字struct定義一個結構。從語法上來看,結構與類很相似,在類中可以包含的成員幾乎都可以包含在結構中。例如,結構中可以定義字段、方法、構造函數、屬性、事件等。定義結構語法如下:
訪問修飾符 struct 結構名
{
//結構成員
}
1 public struct MyPoint 2 { 3 public int x; 4 public int y; 5 6 public MyPoint(int a, int b) 7 { 8 x = a; 9 y = b; 10 } 11 }
在結構中不能定義默認構造函數(即不帶參數的構造函數),但可以定義帶參數的構造函數,如上面代碼定義的結構,定義了帶參數的構造函數。
定義了結構後就可以在代碼中使用,使用結構的方法可以與使用類的方法相同用new關鍵字創建結構,並調用適當的構造函數;同時與類不同的是,結構的實例化可以不使用 new 運算符。 在此情況下不存在構造函數調用,
因而可以提高分配效率。 但是,在初始化所有字段之前,字段將保持未賦值狀態且對象不可用。
1 MyPoint p1 = new MyPoint(); 2 MyPoint p2 = new MyPoint(10, 20); 3 MyPoint p3; 4 p3.x = 100; 5 p3.y = 300; 6 7 Console.WriteLine("p1.x = {0}, p1.y = {1}", p1.x, p1.y); 8 Console.WriteLine("p2.x = {0}, p2.y = {1}", p2.x, p2.y); 9 Console.WriteLine("p3.x = {0}, p3.y = {1}", p3.x, p3.y);
結果如下
p1.x = 0, p1.y = 0 p2.x = 10, p2.y = 20 p3.x = 100, p3.y = 300
對於結構,不像類那樣存在繼承。 一個結構不能從另一個結構或類繼承,而且不能作為一個類的基。 但是,結構從基類 Object 繼承。 結構可實現接口,其方式同類完全一樣。
類是一種引用類型。所謂引用類型,是指變量所包含的是實際數據的地址。而結構是一種值類型,即變量所包含的是實際的數據。引用類型的存儲空間是在堆上分配的,依賴垃圾回收機制釋放所占內存;值類型的存儲空間是在堆棧上分配的,當變量
超出作用域時立即釋放。
用以下代碼來說明類引用類型和結構值類型的區別
1 Console.WriteLine("定義結構p1"); 2 MyPoint p1 = new MyPoint(10, 10); 3 Console.WriteLine("把p1結構賦值給另外兩個結構p2和p3"); 4 MyPoint p2 = p1; 5 MyPoint p3 = p1; 6 7 Console.WriteLine("修改p2結構的值"); 8 p2.x = 100; 9 p2.y = 300; 10 11 Console.WriteLine("修改後結構p1,p2,p3的值分別為:"); 12 Console.WriteLine("p1.x = {0}, p1.y = {1}", p1.x, p1.y); 13 Console.WriteLine("p2.x = {0}, p2.y = {1}", p2.x, p2.y); 14 Console.WriteLine("p3.x = {0}, p3.y = {1}", p3.x, p3.y); 15 16 17 Console.WriteLine("定義類p11"); 18 MyPointClass p11 = new MyPointClass(10, 10); 19 Console.WriteLine("把p11類實例賦值給另外兩個類p22和p33"); 20 MyPointClass p22 = p11; 21 MyPointClass p33 = p11; 22 23 Console.WriteLine("修改p22類實例的值"); 24 p22.x = 100; 25 p22.y = 300; 26 27 Console.WriteLine("修改後類實例p11,p22,p33的值分別為:"); 28 Console.WriteLine("p11.x = {0}, p11.y = {1}", p11.x, p11.y); 29 Console.WriteLine("p22.x = {0}, p22.y = {1}", p22.x, p22.y); 30 Console.WriteLine("p33.x = {0}, p33.y = {1}", p33.x, p33.y);
運行結果
定義結構p1 把p1結構賦值給另外兩個結構p2和p3 修改p2結構的值 修改後結構p1,p2,p3的值分別為: p1.x = 10, p1.y = 10 p2.x = 100, p2.y = 300 p3.x = 10, p3.y = 10 定義類p11 把p11類實例賦值給另外兩個類p22和p33 修改p22類實例的值 修改後類實例p11,p22,p33的值分別為: p11.x = 100, p11.y = 300 p22.x = 100, p22.y = 300 p33.x = 100, p33.y = 300
由於以上原因,相對於類來說,結構是一種輕量級的數據類型,適用於表示占用存儲空間較小的數據類型。如果一個數據類型具有以下幾個特點,則可以將其定義為結構:
1、在邏輯上表示單個值,與基元類型(int、double等)類似
2、占用內存小於16字節
3、不必頻繁轉換為引用類型
用以下代碼測試類與結構的效率
1 DateTime time1 = DateTime.Now; 2 Console.WriteLine("創建999999999個結構,開始於" + time1.ToLongTimeString()); 3 for (int i = 0; i < 999999999; i++) 4 { 5 MyPoint p = new MyPoint(10, 10); 6 } 7 DateTime time2 = DateTime.Now; 8 Console.WriteLine("創建999999999個結構,結束於:" + time2.ToLongTimeString()); 9 Console.WriteLine("共耗時: {0}", time2 - time1); 10 11 time1 = DateTime.Now; 12 Console.WriteLine("創建999999999個類,開始於:" + time1.ToLongTimeString()); 13 for (int i = 0; i < 999999999; i++) 14 { 15 MyPointClass p = new MyPointClass(10, 10); 16 } 17 time2 = DateTime.Now; 18 Console.WriteLine("創建999999999個類,結束於:" + time2.ToLongTimeString()); 19 Console.WriteLine("共耗時: {0}", time2 - time1);
運行結果如下
創建999999999個結構,開始於17:20:35 創建999999999個結構,結束於:17:20:39 共耗時: 00:00:04.0582321 創建999999999個類,開始於:17:20:39 創建999999999個類,結束於:17:20:47 共耗時: 00:00:07.6894398
可以看出創建結構要比創建類花的時間少。