NET中class與struct的區別簡析

來源:互聯網
上載者:User
在沒有class的面向過程的編程時代,struct是封裝資料的利器,沒它不行。但自從物件導向編程以來,class橫空出世,大家高呼著“萬事萬物皆對象”,把class含在嘴裡,握在手裡,基本上使用class可以替代struct的任何場合。但是各位不要忘了“存在必有其價值”,所以struct還是有其作用和優勢的地方的,要知道如何恰到好處的使用,就需先徹底瞭解二者的區別。

 

    很多時候一提起class和struct,可能很多初學朋友看不出它們兄弟倆有啥區別,的確文法幾乎相同,但其本質卻截然不同:class是參考型別,struct是實值型別,也就是說在記憶體中儲存方式有別,由此產生的一系列差異性。所以只有深刻的理解記憶體配置的相關內容,才能更好的駕馭。

    class(類)是物件導向編程的基本概念,是一種自訂資料結構類型,通常包含欄位、屬性、方法、建構函式、索引器、事件等。在.NET中,所有的類都繼承自System.Object類,是一種參考型別,也就是說,當我們new出一個類的執行個體時,對象儲存了該執行個體實際資料的引用地址,而對象的值儲存在託管堆中。

 

    struct(結構)是一種實值型別,用於將一組相關的資訊變數組織成為一個單一的變數實體。所有的結構都繼承自System.ValueType類,是一種實值型別,我們可以像使用int和char一樣去使用struct。struct執行個體分配線上程的堆棧上,它本身儲存了值,而不是指向該值的指標。

 

瞭解了class和struct的本質,我們可以通過分析和實驗來總結二者的區別了:

(1)關於實質:class是參考型別,struct是實值型別
(2)關於職能:class是行為的封裝,用來表述對象,而struct是資料的封裝,用來儲存資料
(3)關於繼承:class支援繼承自類和介面;而struct只能支繼承介面。struct不能從class繼承,也不能作為class的基類。
(4)關於建構函式:class可以聲明無參建構函式,可以聲明解構函式;而struct只能聲明帶參數建構函式,且不能聲明解構函式。
(5)關於執行個體化:class要使用new關鍵字;而struct可以不使用new關鍵字,struct在聲明時就進行了初始化過程,所有的成員變數均預設為0或null。
(6)關於抽象:class可以實抽象類別(abstract),可以聲明抽象函數;而struct不能。
(7)關於重載:class可以聲明protected成員、virtual成員、sealed成員和override成員;而struct不可以,但是值得注意的是,struct可以重載System.Object的3個虛方法,Equals()、ToString()和GetHashTable()。
(8)關於比較:兩個class的比較有Equals和==兩種,即值相等和引用相同;而兩個struct可以直接通過==來判斷。
(9)關於銷毀:class執行個體由記憶體回收機制來保證記憶體的回收處理;而struct變數使用完後立即自動解除記憶體配置。
(10)關於參數傳遞:class變數是以按址方式傳遞;而struct變數是以按值方式傳遞的。

 

    既然class幾乎可以完全替代struct來實現所有的功能,那麼struct還有存在的必要嗎?至少在以下情況下,我們應該考慮使用struct來代替class:

    實現一個用於儲存資料的結構時,可以考慮struct。
    考慮與某些Unmanaged 程式碼通訊的相容性問題時,可以考慮struct。

所有這些是struct有一席之地的理由,當然也許還有其他的更多說法,只是我不知道罷了。

引用一個經典樣本

(1)定義介面

 interface IPerson{
void GetSex();
}

(2)定義類

    public class Person
    {
        public Person()
        {
        }

        public Person(string name, int age)
        {
            _name = name;
            _age = age;
        }

        private string _name;

        public string Name
        {
          get { return _name; }
          set { _name = value; }
        }

        private int _age;

        public int Age
        {
          get { return _age; }
          set { _age = value; }
        }
    }

(3)定義結構

    //可以繼承自介面,不可繼承類或結構
    struct Family: IPerson
    {
        public string name;
        public int age;
        public bool sex;
        public string country;
        public Person person;

        //不可以包含顯式的無參建構函式和解構函式
        public Family(string name, int age,

                  bool sex, string country, Person person)
        {
            this.name = name;
            this.age = age;
            this.sex = sex;
            this.country = country;
            this.person = person;
        }

        //不可以實現protected、virtual、sealed和override成員
        public void GetSex()
        {
            if (sex)
                Console.WriteLine(person.Name + " is a boy.");
            else
                Console.WriteLine(person.Name + " is a girl.");
        }

        public void ShowPerson()
        {
            Console.WriteLine("This is {0} from {1}",

                            new Person(name, 22).Name, country);
        }

        //可以重載ToString虛方法
        public override string ToString()
        {
            return String.Format("{0} is {1}, {2} from {3}",

                person.Name, age, sex ? "Boy" : "Girl", country);
        }
    }

    本文關於 class和struct的討論到此為止,在.NET中,關於class和struct的討論將涉及到對參考型別和實值型別的認識,並且進一步將觸角伸向變數記憶體配置這一進階主題,所以我們有必要來瞭解其運行機制,把握區別和應用場合,以便在平常的系統設計中把握好對這一概念層次的內容。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.