本教程介紹結(jié)構(gòu)的語(yǔ)法和用法。它還涉及類(lèi)與結(jié)構(gòu)之間的重大差異。 示例文件請(qǐng)參見(jiàn)“結(jié)構(gòu)”示例以下載和生成本教程中討論的示例文件。 教程此教程包括兩個(gè)示例。第一個(gè)示例向您展示如何聲明和使用結(jié)構(gòu),而第二個(gè)示例演示向方法傳遞實(shí)例時(shí)結(jié)構(gòu)和類(lèi)之間的差異。還向您介紹下列主題:
示例 1本示例聲明一個(gè)結(jié)構(gòu),它有三個(gè)成員:一個(gè)屬性、一個(gè)方法和一個(gè)私有字段。本示例創(chuàng)建該結(jié)構(gòu)的一個(gè)實(shí)例,并將其投入使用: // struct1.cs using System; struct SimpleStruct { private int xval; public int X { get { return xval; } set { if (value < 100) xval = value; } } public void DisplayX() { Console.WriteLine("The stored value is: {0}", xval); } } class TestClass { public static void Main() { SimpleStruct ss = new SimpleStruct(); ss.X = 5; ss.DisplayX(); } } 輸出The stored value is: 5 結(jié)構(gòu)與類(lèi)結(jié)構(gòu)可能看似類(lèi),但存在一些重要差異,應(yīng)引起注意。首先,類(lèi)為引用類(lèi)型,而結(jié)構(gòu)為值類(lèi)型。使用結(jié)構(gòu),您可以創(chuàng)建行為類(lèi)似內(nèi)置類(lèi)型的對(duì)象,同時(shí)享有它們的好處。 堆還是堆棧?在類(lèi)上調(diào)用“新建”(New) 運(yùn)算符時(shí),它將在堆上進(jìn)行分配。但是,當(dāng)實(shí)例化結(jié)構(gòu)時(shí),將在堆棧上創(chuàng)建結(jié)構(gòu)。這樣將產(chǎn)生性能增益。而且,您不會(huì)像對(duì)待類(lèi)那樣處理對(duì)結(jié)構(gòu)實(shí)例的引用。您將直接對(duì)結(jié)構(gòu)實(shí)例進(jìn)行操作。鑒于此原因,向方法傳遞結(jié)構(gòu)時(shí),結(jié)構(gòu)將通過(guò)值傳遞,而不是作為引用傳遞。 示例 2本示例展示當(dāng)向方法傳遞結(jié)構(gòu)時(shí),將傳遞該結(jié)構(gòu)的副本,而傳遞類(lèi)實(shí)例時(shí),將傳遞一個(gè)引用。 // struct2.cs using System; class TheClass { public int x; } struct TheStruct { public int x; } class TestClass { public static void structtaker(TheStruct s) { s.x = 5; } public static void classtaker(TheClass c) { c.x = 5; } public static void Main() { TheStruct a = new TheStruct(); TheClass b = new TheClass(); a.x = 1; b.x = 1; structtaker(a); classtaker(b); Console.WriteLine("a.x = {0}", a.x); Console.WriteLine("b.x = {0}", b.x); } } 輸出a.x = 1 b.x = 5 代碼討論本示例的輸出表明:當(dāng)向 classtaker 方法傳遞類(lèi)實(shí)例時(shí),只更改了類(lèi)字段的值。但是向 structtaker 方法傳遞結(jié)構(gòu)實(shí)例并不更改結(jié)構(gòu)字段。這是因?yàn)橄?structtaker 方法傳遞的是結(jié)構(gòu)的副本,而向 classtaker 方法傳遞的是對(duì)類(lèi)的引用。 構(gòu)造函數(shù)和繼承結(jié)構(gòu)可以聲明構(gòu)造函數(shù),但它們必須帶參數(shù)。聲明結(jié)構(gòu)的默認(rèn)(無(wú)參數(shù))構(gòu)造函數(shù)是錯(cuò)誤的。結(jié)構(gòu)成員不能有初始值設(shè)定項(xiàng)。總是提供默認(rèn)構(gòu)造函數(shù)以將結(jié)構(gòu)成員初始化為它們的默認(rèn)值。 使用 New 運(yùn)算符創(chuàng)建結(jié)構(gòu)對(duì)象時(shí),將創(chuàng)建該結(jié)構(gòu)對(duì)象,并且調(diào)用適當(dāng)?shù)臉?gòu)造函數(shù)。與類(lèi)不同的是,結(jié)構(gòu)的實(shí)例化可以不使用 New 運(yùn)算符。如果不使用“新建”(new),那么在初始化所有字段之前,字段將保持未賦值狀態(tài),且對(duì)象不可用。 對(duì)于結(jié)構(gòu),不像類(lèi)那樣存在繼承。一個(gè)結(jié)構(gòu)不能從另一個(gè)結(jié)構(gòu)或類(lèi)繼承,而且不能作為一個(gè)類(lèi)的基。但是,結(jié)構(gòu)從基類(lèi)對(duì)象繼承。結(jié)構(gòu)可實(shí)現(xiàn)接口,而且實(shí)現(xiàn)方式與類(lèi)實(shí)現(xiàn)接口的方式完全相同。以下是結(jié)構(gòu)實(shí)現(xiàn)接口的代碼片段: interface IImage { void Paint(); } struct Picture : IImage { public void Paint() { // painting code goes here } private int x, y, z; // other struct members } 結(jié)構(gòu)上的屬性通過(guò)使用屬性可以自定義結(jié)構(gòu)在內(nèi)存中的布局方式。例如,可以使用 StructLayout(LayoutKind.Explicit) 和 FieldOffset 屬性創(chuàng)建在 C/C++ 中稱(chēng)為聯(lián)合的布局方式。 using System.Runtime.InteropServices; [StructLayout(LayoutKind.Explicit)] struct TestUnion { [FieldOffset(0)] public int i; [FieldOffset(0)] public double d; [FieldOffset(0)] public char c; [FieldOffset(0)] public byte b1; } 在上一個(gè)代碼段中, 以下是字段從其他顯式設(shè)置的位置開(kāi)始的另一個(gè)示例: using System.Runtime.InteropServices; [StructLayout(LayoutKind.Explicit)] struct TestExplicit { [FieldOffset(0)] public long lg; [FieldOffset(0)] public int i1; [FieldOffset(4)] public int i2; [FieldOffset(8)] public double d; [FieldOffset(12)] public char c; [FieldOffset(14)] public byte b1; }
結(jié)束語(yǔ)結(jié)構(gòu)使用簡(jiǎn)單,并且有時(shí)證明很有用。但要牢記:結(jié)構(gòu)在堆棧中創(chuàng)建,并且您不是處理對(duì)結(jié)構(gòu)的引用,而是直接處理結(jié)構(gòu)。每當(dāng)需要一種將經(jīng)常使用的類(lèi)型,而且大多數(shù)情況下該類(lèi)型只是一些數(shù)據(jù)時(shí),結(jié)構(gòu)可能是最佳選擇。 |
只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問(wèn)
管理
|
||