深入解析C#編程中struct所定義的結(jié)構(gòu)
結(jié)構(gòu)是使用 struct 關(guān)鍵字定義的,例如:
public struct PostalAddress
{
// Fields, properties, methods and events go here...
}
結(jié)構(gòu)與類共享大多數(shù)相同的語法,但結(jié)構(gòu)比類受到的限制更多:
- 在結(jié)構(gòu)聲明中,除非字段被聲明為 const 或 static,否則無法初始化。
- 結(jié)構(gòu)不能聲明默認(rèn)構(gòu)造函數(shù)(沒有參數(shù)的構(gòu)造函數(shù))或析構(gòu)函數(shù)。
- 結(jié)構(gòu)在賦值時進(jìn)行復(fù)制。將結(jié)構(gòu)賦值給新變量時,將復(fù)制所有數(shù)據(jù),并且對新副本所做的任何修改不會更改原始副本的數(shù)據(jù)。在使用值類型的集合(如 Dictionary<string, myStruct>)時,請務(wù)必記住這一點。
- 結(jié)構(gòu)是值類型,而類是引用類型。
- 與類不同,結(jié)構(gòu)的實例化可以不使用 new 運算符。
- 結(jié)構(gòu)可以聲明帶參數(shù)的構(gòu)造函數(shù)。
- 一個結(jié)構(gòu)不能從另一個結(jié)構(gòu)或類繼承,而且不能作為一個類的基。所有結(jié)構(gòu)都直接繼承自 System.ValueType,后者繼承自 System.Object。
- 結(jié)構(gòu)可以實現(xiàn)接口。
- 結(jié)構(gòu)可用作可以為 null 的類型,因而可向其賦 null 值。
struct 類型適于表示 Point、Rectangle 和 Color 等輕量對象。盡管使用自動實現(xiàn)的屬性將一個點表示為類同樣方便,但在某些情況下使用結(jié)構(gòu)更加有效。例如,如果聲明一個 1000 個 Point 對象組成的數(shù)組,為了引用每個對象,則需分配更多內(nèi)存;這種情況下,使用結(jié)構(gòu)可以節(jié)約資源。因為 .NET Framework 包含一個名為 Point 的對象,所以本示例中的結(jié)構(gòu)命名為“CoOrds”。
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
為結(jié)構(gòu)定義默認(rèn)(無參數(shù))構(gòu)造函數(shù)是錯誤的。在結(jié)構(gòu)體中初始化實例字段也是錯誤的。只能通過兩種方式初始化結(jié)構(gòu)成員:一是使用參數(shù)化構(gòu)造函數(shù),二是在聲明結(jié)構(gòu)后分別訪問成員。對于任何私有成員或以其他方式設(shè)置為不可訪問的成員,只能在構(gòu)造函數(shù)中進(jìn)行初始化。
如果使用 new 運算符創(chuàng)建結(jié)構(gòu)對象,則會創(chuàng)建該結(jié)構(gòu)對象,并調(diào)用適當(dāng)?shù)臉?gòu)造函數(shù)。與類不同,結(jié)構(gòu)的實例化可以不使用 new 運算符。在此情況下不存在構(gòu)造函數(shù)調(diào)用,因而可以提高分配效率。但是,在初始化所有字段之前,字段將保持未賦值狀態(tài)且對象不可用。
當(dāng)結(jié)構(gòu)包含引用類型作為成員時,必須顯式調(diào)用該成員的默認(rèn)構(gòu)造函數(shù),否則該成員將保持未賦值狀態(tài)且該結(jié)構(gòu)不可用。(這將導(dǎo)致編譯器錯誤 CS0171。)
對于結(jié)構(gòu),不像類那樣存在繼承。一個結(jié)構(gòu)不能從另一個結(jié)構(gòu)或類繼承,而且不能作為一個類的基。但是,結(jié)構(gòu)從基類 Object 繼承。結(jié)構(gòu)可實現(xiàn)接口,其方式同類完全一樣。
無法使用 struct 關(guān)鍵字聲明類。在 C# 中,類與結(jié)構(gòu)在語義上是不同的。結(jié)構(gòu)是值類型,而類是引用類型。
除非需要引用類型語義,將較小的類聲明為結(jié)構(gòu),可以提高系統(tǒng)的處理效率。
示例 1
描述
下面的示例演示使用默認(rèn)構(gòu)造函數(shù)和參數(shù)化構(gòu)造函數(shù)的 struct 初始化。
代碼
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
// Declare and initialize struct objects.
class TestCoOrds
{
static void Main()
{
// Initialize:
CoOrds coords1 = new CoOrds();
CoOrds coords2 = new CoOrds(10, 10);
// Display results:
Console.Write("CoOrds 1: ");
Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
Console.Write("CoOrds 2: ");
Console.WriteLine("x = {0}, y = {1}", coords2.x, coords2.y);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
輸出:
CoOrds 1: x = 0, y = 0 CoOrds 2: x = 10, y = 10
示例 2
描述
下面舉例說明了結(jié)構(gòu)特有的一種功能。它在不使用 new 運算符的情況下創(chuàng)建 CoOrds 對象。如果將 struct 換成 class,程序?qū)⒉粫幾g。
代碼
public struct CoOrds
{
public int x, y;
public CoOrds(int p1, int p2)
{
x = p1;
y = p2;
}
}
// Declare a struct object without "new."
class TestCoOrdsNoNew
{
static void Main()
{
// Declare an object:
CoOrds coords1;
// Initialize:
coords1.x = 10;
coords1.y = 20;
// Display results:
Console.Write("CoOrds 1: ");
Console.WriteLine("x = {0}, y = {1}", coords1.x, coords1.y);
// Keep the console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
輸出:
CoOrds 1: x = 10, y = 20
- C#調(diào)用C類型dll入?yún)閟truct的問題詳解
- C#使用struct直接轉(zhuǎn)換下位機(jī)數(shù)據(jù)的示例代碼
- C#中的只讀結(jié)構(gòu)體(readonly struct)詳解
- 區(qū)分C# 中的 Struct 和 Class
- 淺析C# 結(jié)構(gòu)體struct
- C#如何從byte[]中直接讀取Structure實例詳解
- C#中結(jié)構(gòu)(struct)的部分初始化和完全初始化實例分析
- C#中struct和class的區(qū)別詳解
- C# Struct的內(nèi)存布局問題解答
- 深入探討C#中的結(jié)構(gòu)struct
- c# Struct的一些問題分析
相關(guān)文章
C# Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的應(yīng)用(下)
本篇文章是對C#中ExpandoObject,DynamicObject,DynamicMetaOb的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05
如何用C#找出數(shù)組中只出現(xiàn)了一次的數(shù)字
數(shù)組從字面上理解就是存放一組數(shù),下面這篇文章主要給大家介紹了關(guān)于如何用C#找出數(shù)組中只出現(xiàn)了一次的數(shù)字,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-12-12

