隨風(fēng)設(shè)計(jì)

          隨風(fēng)設(shè)計(jì)

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            11 隨筆 :: 0 文章 :: 0 評(píng)論 :: 0 Trackbacks

          本教程介紹結(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)之間的差異。還向您介紹下列主題:

          • 結(jié)構(gòu)與類(lèi)
          • 堆還是堆棧?
          • 構(gòu)造函數(shù)和繼承
          • 結(jié)構(gòu)上的屬性

          示例 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è)代碼段中,TestUnion 的所有字段都從內(nèi)存中的同一位置開(kāi)始。

          以下是字段從其他顯式設(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;
          }

          i1i2 這兩個(gè) int 字段共享與 lg 相同的內(nèi)存位置。使用平臺(tái)調(diào)用時(shí),這種結(jié)構(gòu)布局控制很有用。

          結(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)可能是最佳選擇。

          posted on 2006-08-17 11:37 曹賢 閱讀(200) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 镇平县| 绵阳市| 屏边| 达尔| 静海县| 黄浦区| 丹东市| 九寨沟县| 绍兴县| 大冶市| 喀喇沁旗| 台山市| 曲麻莱县| 永清县| 招远市| 乐昌市| 东城区| 顺义区| 阿拉尔市| 兰坪| 甘泉县| 新田县| 察哈| 霍林郭勒市| 佛山市| 清徐县| 宜州市| 云梦县| 尉犁县| 泸定县| 文安县| 韶山市| 明水县| 桑日县| 阳信县| 元谋县| 遵化市| 铜陵市| 通州市| 祁东县| 宾阳县|