首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# 結構與類別的完整比較總結

     編輯:關於C#

總結起來,結構與類別主要有以下差異:

核心差異

  1. 類型分類:結構是實值類型,類別是參考類型。結構實例存放在堆疊,類別僅在堆疊存放參考位址,實際值存放在堆積。
  2. 資料傳遞適用性:基於第 1 點,類別物件通常用來傳遞大量資料,結構物件則用來傳遞少量資料。
  3. 繼承支援:類別可以被繼承,結構不支援繼承。
  4. Null 指派:結構物件不能像類別物件一樣指派為 null。
  5. 解構函式:結構不能像類別一樣定義解構函式。
  6. 抽象修飾詞:結構不能像類別一樣定義為 abstract。
  7. 方法覆寫限制:結構中不能覆寫方法,除非是 object 類型的以下方法:Equals()、GetHashCode()、GetType()、ToString()。若要讓結構具有多型特性,可讓其實作介面。
  8. 事件執行緒安全性:類別中定義的事件是執行緒安全的,結構則不是。
  9. 預設建構函式:結構總是具有一個預設的公用無參數建構函式,但不能像類別一樣定義私有無參數建構函式(結構也不能再定義公用無參數建構函式,這與類別不同)。
  10. 靜態建構函式:類別的靜態建構函式會被呼叫,結構卻不會。因此在結構中定義靜態建構函式雖可編譯通過,但無效果。
  11. Volatile 欄位:結構不能像類別一樣定義 volatile 欄位。volatile 主要用於平行處理,相當於方法主體的 lock。
  12. sizeof 運算子:可對結構類型使用 sizeof,對類別則不行。
  13. 欄位自動初始化:類別欄位會自動初始化為 0/false/null,結構則不會。
  14. 欄位直接初始化:結構中不能直接對欄位初始化,類別則可以。
  15. Equals 行為差異:結構與類別對 System.Object.Equals() 體現不同。結構為實值類型,Equals() 比較兩物件值是否相等;類別為參考類型,Equals() 比較兩者參考位址(指標)是否相等。

程式碼範例說明

第 9 點:建構函式差異

struct Me {
    private Me() // compile-time error
    { }
}

class Me {
    private Me() // runs Ok
    { }
}

第 10 點:靜態建構函式差異

struct myStructure {
    static myStructure() {
        Console.WriteLine("This is me a structure");
    }
}
class myClass {
    static myClass() {
        Console.WriteLine("This is me a class");
    }
}
class Program {
    static void Main(string[] args) {
        myStructure s = new myStructure(); // Nothing happen
        myClass c = new myClass(); // Will output "This is me a class"
        Console.Read();
    }
}

第 14 點:欄位初始化差異

struct myStructure {
    public string x = 2; // Not allowed
}
class myClass {
    public string x = 2; // Allowed
}

第 15 點:Equals 比較行為差異

struct StructurePerson {
    public string FirstName;
    public string LastName;
}
class ClassPerson {
    public string FirstName;
    public string LastName;
}

// 測試程式碼
StructurePerson strX = new StructurePerson();
strX.LastName = "Bejaoui";
strX.FirstName = "Bechir";
StructurePerson strY = new StructurePerson();
strY.LastName = "Bejaoui";
strY.FirstName = "Bechir";

if (strX.Equals(strY))
    Console.WriteLine("strX = strY"); // 顯示此行
else
    Console.WriteLine("strX != strY");

ClassPerson clsX = new ClassPerson();
clsX.LastName = "Bejaoui";
clsX.FirstName = "Bechir";
ClassPerson clsY = new ClassPerson();
clsY.LastName = "Bejaoui";
clsY.FirstName = "Bechir";

if (clsX.Equals(clsY))
    Console.WriteLine("clsX = clsY");
else
    Console.WriteLine("clsX != clsY"); // 顯示此行

由於結構是實值類型,Equals() 比較值是否相等;類別是參考類型,Equals() 比較參考位址。clsX 與 clsY 是兩個不同物件,堆疊位址不相等。若修改程式碼:ClassPerson clsY = clsX; 直接指派,則兩物件參考位址相等,Equals() 回傳 true。

實值類型與參考類型相等性比較是複雜問題。可透過覆寫 Equals() 增強或修改比較邏輯,覆寫 Equals() 還必須覆寫 GetHashCode()。參考類型還可使用靜態方法 ReferenceEquals()。也可多載 == 運算子。String 物件特殊,因使用 Immutable 模式。雖然 String 是參考類型,但直接定義兩個值相同的 String 物件,因採用 Immutable 模式,這兩物件其實是同一物件,參考位址相同,不僅 Equals() 回傳 true,ReferenceEquals() 也回傳 true。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved