C#編程(十八)----------C#中的結構

C#中的結構函數

假設有一個類:佈局

class Dimensions性能

{this

public double Length;spa

public double Width;設計

}對象

定義了一個類,它只存儲某一項的長度和寬度.嘉定編寫一個佈置家居的程序,讓人們試着在計算機上從新佈置傢俱,並存儲每件傢俱的維度.使字段變爲共有字段,就會違背變成規則,但咱們實際上並不須要類的所有功能.如今只有兩個數字,把他們當作一堆來處理,要比單個處理方便一些.既不須要不少方法,也不須要從類中繼承,也不但願.NET運行庫在堆中遇到麻煩和性能問題,值存儲兩個double類型的數據便可.繼承

爲此,只須要修改代碼,使用關鍵字struct代替class,定義一個結構而不是類接口

struct Dimensions內存

{

public double Length;

public double Width;

}

爲結構定義函數與味蕾定義函數徹底相同.

 

struct Dimensions

        {

            public double Length;

            public double Width;

            public Dimensions(double length, double width)

            {

                this.Length = length;

                this.Width = width;

            }

            public double Diagonal

            {

                get

                {

                    return Math.Sqrt(Length * Length + Width * Width);

                }

            }

        }

 

 

結構是值類型,不是引用類型.他們存儲在棧中或存儲爲內聯,其生存期的限制與簡單的數據類型同樣.

結構不支持繼承.

對於結構構造函數的工做方式有一些區別.尤爲是編譯器老是提供一個無參數的默認構造函數,他是不容許替換的.

使用結構,能夠指定字段如何在內存中的佈局.

 

由於結構其實是把數據項組合在一塊兒,有時大多數或者所有的字段都聲明爲public.嚴格來講,這是違背.NET代碼的規則的,根據Microsoft,字段(除了const字段以外)應該老是私有的,並由共有屬性封裝.可是對於簡單的結構,共有字段仍是能夠接受的.

 

結構是值類型

雖然結構是值類型,可是在語法上經常能夠把他們當作類來處理.例如,上面的Dimension類的定義中,能夠編寫下面的代碼:

Dimensions point = new Dimensions();

point.Lenth=3;

point.Width=6;

注意,由於結構是值類型,因此new運算符與類和其餘引用類型的工做方式不一樣.new運算符並不分配隊中的內存,而是隻調用相應的構造函數,根據傳送給他的參數,初始化全部的字段.對於結構,能夠編寫下面代碼:

Dimensions point;

point.Length=3;

point.Width=6;

若是Dimensions是一個類,就會產生錯誤,由於point包含一個爲初始化的引用----不知想任何地方的一個地址,因此不能給其字段設置值.可是對於結構,變量聲明其實是維護整個結構在棧中分配空間,因此就能夠爲他賦值了.

可是若是這樣:

Dimensions point;

double d=point.Length;

編譯器就會產生一個錯誤,緣由是使用了未初始化的變量.

 

結構遵循其餘數據類型都遵循的規則:在使用前全部的元素都必須進行初始化.在結構上調用new運算符,或者給全部的字段分別賦值,結構就徹底初始化了.若是結構定義爲類的成員字段,在初始化包含的對象時,該結構會自動初始化爲0.

結構是會影響性能的值類型.

 

結構不失爲繼承設計的.這意味着:他不能從一個結構中繼承.惟一的例外是對應的結構(C#中的其餘類型同樣)最終派生於類System.Object.所以結構能夠訪問System.Object的方法.在結構中,甚至能夠重寫System.Objetc中的方法----如重寫ToString()方法.結構的繼承鏈是:每一個結構派生自System.ValueType,System.ValueType類又派生自System.Object.ValueType並無給Object添加任何新成員,但提供了一些更適合結構的額實現方式.注意,不能爲結構提供其餘類:每一個結構都派生自ValueType.

 

結構的構造函數

爲結構定義構造函數的方式與爲類定義構造函數的方式相同,但不容許定義無參數的構造函數.禁止在C#的結構內使用無參數的構造函數.

前面說過,默認構造函數把數值字段都初始化爲0,把引用類型字段初始化爲null,且老是隱式的給出,及時提供了其餘帶參數的構造函數,也是如此,提供字段的初始值也不鞥呢繞過默認構造函數.

例如:

struct Dimensions

        {

            public double Length=1;

            public double Width=2;           

        }

會出現錯誤,結構中不能有實例字段初始值設定項,若是是類就不會出現這個錯誤.

另外,能夠向類那樣爲結構提供Close()Dispose()方法.

struct總結:struct 類型適於表示 PointRectangle  Color 等輕量對象。爲結構定義默認(無參數)構造函數是錯誤的。 在結構體中初始化實例字段也是錯誤的。 只能經過兩種方式初始化結構成員:一是使用參數化構造函數,二是在聲明結構後分別訪問成員。 對於任何私有成員或以其餘方式設置爲不可訪問的成員,只能在構造函數中進行初始化。

若是使用 new 運算符建立結構對象,則會建立該結構對象,並調用適當的構造函數。 與類不一樣,結構的實例化能夠不使用 new 運算符。 在此狀況下不存在構造函數調用,於是能夠提升分配效率。 可是,在初始化全部字段以前,字段將保持未賦值狀態且對象不可用。

當結構包含引用類型做爲成員時,必須顯式調用該成員的默認構造函數,不然該成員將保持未賦值狀態且該結構不可用。 (這將致使編譯器錯誤 CS0171。)

對於結構,不像類那樣存在繼承。 一個結構不能從另外一個結構或類繼承,並且不能做爲一個類的基。 可是,結構從基類 Object 繼承。 結構可實現接口,其方式同類徹底同樣。

沒法使用 struct 關鍵字聲明類。 在 C# 中,類與結構在語義上是不一樣的。 結構是值類型,而類是引用類型。

相關文章
相關標籤/搜索