在描述他們之間區別之前,首先得明白他們的定義。
一、結構體
1.定義:
在 C# 中,結構體是值類型數據結構。它使得一個單一變量可以存儲各種數據類型的相關數據。struct 關鍵字用於創建結構體。用來封裝多個不同類型的變量
例如,您可以按照如下的方式聲明 Book 結構:
struct Books { public string title; public string author; public string subject; public int book_id; };
下面的程序演示了結構的用法:
using System;
using System.Text;
struct Books
{
public string title;
public string author;
public string subject;
public int book_id;
};
public class testStructure
{
public static void Main(string[] args)
{
Books Book1; /* 聲明 Book1,類型為 Book */
Books Book2; /* 聲明 Book2,類型為 Book */
/* book 1 詳述 */
Book1.title = "C Programming";
Book1.author = "Nuha Ali";
Book1.subject = "C Programming Tutorial";
Book1.book_id = 6495407;
/* book 2 詳述 */
Book2.title = "Telecom Billing";
Book2.author = "Zara Ali";
Book2.subject = "Telecom Billing Tutorial";
Book2.book_id = 6495700;
/* 打印 Book1 信息 */
Console.WriteLine( "Book 1 title : {0}", Book1.title);
Console.WriteLine("Book 1 author : {0}", Book1.author);
Console.WriteLine("Book 1 subject : {0}", Book1.subject);
Console.WriteLine("Book 1 book_id :{0}", Book1.book_id);
/* 打印 Book2 信息 */
Console.WriteLine("Book 2 title : {0}", Book2.title);
Console.WriteLine("Book 2 author : {0}", Book2.author);
Console.WriteLine("Book 2 subject : {0}", Book2.subject);
Console.WriteLine("Book 2 book_id : {0}", Book2.book_id);
Console.ReadKey();
}
}
當上面的代碼被編譯和執行時,它會產生下列結果:
Book 1 title : C Programming Book 1 author : Nuha Ali Book 1 subject : C Programming Tutorial Book 1 book_id : 6495407 Book 2 title : Telecom Billing Book 2 author : Zara Ali Book 2 subject : Telecom Billing Tutorial Book 2 book_id : 6495700
C# 中的結構有以下特點:
- 結構可帶有方法、字段、索引、屬性、運算符方法和事件。
- 結構可定義構造函數,但不能定義析構函數。但是,您不能為結構定義無參構造函數。無參構造函數(默認)是自動定義的,且不能被改變。
- 與類不同,結構不能繼承其他的結構或類。
- 結構不能作為其他結構或類的基礎結構。
- 結構可實現一個或多個接口。
- 結構成員不能指定為 abstract、virtual 或 protected。
- 當您使用 New 操作符創建一個結構對象時,會調用適當的構造函數來創建結構。與類不同,結構可以不使用 New 操作符即可被實例化。
- 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被賦值,對象才被使用。
二、類
1.定義:類的定義是以關鍵字 class 開始,后跟類的名稱。類的主體,包含在一對花括號內。
三、結構體和類的區別
1.首先是語法定義上的區別啦,這個就不用多說了.定義類使用關鍵字class 定義結構使用關鍵字struct。
定義類的語法
class Person { private string name; private int age; public void SayHi() { Console.WriteLine("Hello,My Name is "+this.name+",My Age is "+this.age); } }
定義結構的語法.
struct Rectangle
{
private int width;
private int height;
public int GetArea()
{
return this.width * height;
}
}
2.結構體中聲明的字段無法賦予初值,類可以:
public class AA
{
// 類中的字段可以自定義默認值,也可以只聲明
public int a = 1;
// 只聲明的字段
public int b;
public int D{get;}
// 默認構造方法
public AA()
{
}
// 自定義構造方法,可以不用初始化沒有自定義默認值的字段和屬性
public AA(int x)
{
}
}
public struct BB
{
// 實例字段,不能在聲明的時候給出默認值
public int a;
// 靜態字段,外界可以通過結構體名訪問,可以自定義默認值,如果沒給,系統默認值0。
public static int b = 10;
// 屬性,有默認返回值
public int C{get{return 1;}}
// 屬性,沒有默認返回值
public int D{get;}
// 靜態屬性
public static int E{get;}
// 自定義的構造方法,必須初始化所有沒有自定義默認值的字段和屬性
public BB(int x)
{
a = 1;
D = x;
}
public void Test()
{
// 在結構體內部(類也可以)可以使用只聲明沒有自定義默認值的字段或屬性,結果是該類型的默認值
int f = a;
f = D;
}
}
其實從本質上來說,類和結構的字段都是不能有初始值的.只不過微軟在語法上允許我們在定義類的字段的時候為其賦值.但是背后微軟其實是把賦值的執行代碼放到構造函數中去執行的. 而結構體微軟卻不幫我們這樣做.
3.結構體的構造函數中,必須為結構體所有字段賦值,類的構造函數無此限制:
首先,關於隱式構造函數.我們知道,在1個類中如果我們沒有為類寫任意的構造函數,那么C#編譯器在編譯的時候會自動的為這個類生成1個無參數的構造函數.我們將這個構造函數稱之為隱式構造函數 但是一旦我們為這個類寫了任意的1個構造函數的時候,這個隱式的構造函數就不會自動生成了.在結構中,就不是這樣了,在結構中隱式的構造函數無論如何都存在。所以程序員不能手動的為結構添加1個無參數的構造函數。
4.結構是值類型,它在棧中分配空間;而類是引用類型,它在堆中分配空間,棧中保存的只是引用(這是他們最大的區別)。
結構類型直接存儲成員數據,讓其他類的數據位於堆中,位於棧中的變量保存的是指向堆中數據對象的引用。
C# 中的簡單類型,如int、double、bool等都是結構類型。如果需要的話,甚至可以使用結構類型結合運算符運算重載,再為 C# 語言創建出一種新的值類型來。
由於結構是值類型,並且直接存儲數據,因此在一個對象的主要成員為數據且數據量不大的情況下,使用結構會帶來更好的性能。
5.其他區別
Struct變量使用完之后就自動解除內存分配,Class實例有垃圾回收機制來保證內存的回收處理。
四、結構和類的適用場合分析:
- 1、當堆棧的空間很有限,且有大量的邏輯對象時,創建類要比創建結構好一些;
- 2、對於點、矩形和顏色這樣的輕量對象,假如要聲明一個含有許多個顏色對象的數組,則CLR需要為每個對象分配內存,在這種情況下,使用結構的成本較低;
- 3、在表現抽象和多級別的對象層次時,類是最好的選擇,因為結構不支持繼承。
- 4、大多數情況下,目標類型只是含有一些數據,或者以數據為主。