C#之結(jié)構(gòu)struct(轉(zhuǎn))

結(jié)構(gòu)是使用 struct 關(guān)鍵字定義的,與類相似爹谭,都表示可以包含數(shù)據(jù)成員和函數(shù)成員的數(shù)據(jù)結(jié)構(gòu)祟牲。 一般情況下隙畜,我們很少使用結(jié)構(gòu),而且很多人也并不建議使用結(jié)構(gòu)说贝,但作為.NET Framework 一般型別系統(tǒng)中的一個基本架構(gòu)议惰,還是有必要了解一下的。

結(jié)構(gòu)的特征: 結(jié)構(gòu)是一種值類型乡恕,并且不需要堆分配言询。 結(jié)構(gòu)的實例化可以不使用?new?運算符。

在結(jié)構(gòu)聲明中傲宜,除非字段被聲明為?const 或 static倍试,否則無法初始化。 結(jié)構(gòu)類型永遠不是抽象的蛋哭,并且始終是隱式密封的,因此在結(jié)構(gòu)聲明中不允許使用abstract和sealed修飾符涮母。

結(jié)構(gòu)不能聲明默認構(gòu)造函數(shù)(沒有參數(shù)的構(gòu)造函數(shù))或析構(gòu)函數(shù)谆趾,但可以聲明帶參數(shù)的構(gòu)造函數(shù)。 結(jié)構(gòu)可以實現(xiàn)接口叛本,但不能從另一個結(jié)構(gòu)或類繼承沪蓬,而且不能作為一個類的基,所有結(jié)構(gòu)都直接繼承自System.ValueType来候,后者繼承自?System.Object跷叉。 結(jié)構(gòu)在賦值時進行復制。?將結(jié)構(gòu)賦值給新變量時营搅,將復制所有數(shù)據(jù)云挟,并且對新副本所做的任何修改不會更改原始副本的數(shù)據(jù)。?在使用值類型的集合(如 Dictionary)時转质,請務(wù)必記住這一點园欣。 結(jié)構(gòu)類型的變量直接包含了該結(jié)構(gòu)的數(shù)據(jù),而類類型的變量所包含的只是對相應(yīng)數(shù)據(jù)的一個引用(被引用的數(shù)據(jù)稱為“對象”)休蟹。但是結(jié)構(gòu)仍可以通過ref和out參數(shù)引用方式傳遞給函數(shù)成員沸枯。 結(jié)構(gòu)可用作可以為 null 的類型日矫,因而可向其賦 null 值。

structA

{publicintx;//不能直接對其進行賦值publicinty;publicstaticstringstr =null;//靜態(tài)變量可以初始化publicA(intx,inty)//帶參數(shù)的構(gòu)造函數(shù){this.x =x;this.y =y;

Console.WriteLine("x={0},y={1},str={2}", x, y,str);

}

}classProgram

{staticvoidMain(string[] args)

{

A a=newA(1,2);

A a1=a;

a.x=10;

Console.WriteLine("a1.x={0}",a1.x);

Console.Read();

}

}

結(jié)果為:x=1,y=2,str= ???????????a1.x=1 此時a1.x值為1是因為绑榴,將a賦值給a1是對值進行復制哪轿,因此,a1不會受到a.x賦值得改變而改變翔怎。

但如果A是類窃诉,這時a和a1里的x引用的是同一個地址,則a1.x的值會輸出10姓惑。

結(jié)構(gòu)的裝箱與拆箱

我們知道褐奴,一個類類型的值可以轉(zhuǎn)換為?object?類型或由該類實現(xiàn)的接口類型,這只需在編譯時把對應(yīng)的引用當作另一個類型處理即可于毙。 與此類似敦冬,一個object?類型的值或者接口類型的值也可以被轉(zhuǎn)換回類類型而不必更改相應(yīng)的引用。當然唯沮,在這種情況下脖旱,需要進行運行時類型檢查。 由于結(jié)構(gòu)不是引用類型介蛉,上述操作對結(jié)構(gòu)類型是以不同的方式實現(xiàn)的萌庆。 當結(jié)構(gòu)類型的值被轉(zhuǎn)換為object?類型或由該結(jié)構(gòu)實現(xiàn)的接口類型時,就會執(zhí)行一次裝箱操作币旧。 反之践险,當?object?類型的值或接口類型的值被轉(zhuǎn)換回結(jié)構(gòu)類型時,會執(zhí)行一次拆箱操作吹菱。 與對類類型進行的相同操作相比巍虫,主要區(qū)別在于: 裝箱操作會把相關(guān)的結(jié)構(gòu)值復制為已被裝箱的實例,而拆箱則會從已被裝箱的實例中復制出一個結(jié)構(gòu)值鳍刷。 因此占遥,在裝箱或拆箱操作后,對“箱”外的結(jié)構(gòu)進行的更改不會影響已被裝箱的結(jié)構(gòu)输瓜。

structProgram

{staticvoidMain(string[] args)

{inti =1;objecto = i;//隱式裝箱i =123;

Console.WriteLine("i={0},o={1}",i,o);

Console.Read();

}

}//結(jié)果為:i=123,o=1

結(jié)構(gòu)與構(gòu)造函數(shù)

我們知道結(jié)構(gòu)不能使用默認的構(gòu)造函數(shù)瓦胎,只能使用帶參數(shù)的構(gòu)造函數(shù),當定義帶參數(shù)的構(gòu)造函數(shù)時尤揣,一定要完成結(jié)構(gòu)所有字段的初始化搔啊,如果沒有完成所有字段的初始化,編譯時會發(fā)生錯誤-北戏。 結(jié)構(gòu)可以使用靜態(tài)構(gòu)造函數(shù)嗎坯癣? 可以,結(jié)構(gòu)的靜態(tài)構(gòu)造函數(shù)與類的靜態(tài)構(gòu)造函數(shù)所遵循的規(guī)則大體相同最欠。 結(jié)構(gòu)的靜態(tài)構(gòu)造函數(shù)何時將觸發(fā)呢示罗? 結(jié)構(gòu)的實例成員被引用惩猫,結(jié)構(gòu)的靜態(tài)成員被引用,結(jié)構(gòu)顯示聲明的構(gòu)造函數(shù)被調(diào)用蚜点。 但是創(chuàng)建結(jié)構(gòu)類型的默認值不會觸發(fā)靜態(tài)構(gòu)造函數(shù)轧房。為什么結(jié)構(gòu)不能自定義無參數(shù)的構(gòu)造函數(shù)? 結(jié)構(gòu)類型的構(gòu)造函數(shù)與類的構(gòu)造函數(shù)類似绍绘,用來初始化結(jié)構(gòu)的成員變量奶镶,但是struct不能包含顯式默認構(gòu)造函數(shù), 因為編譯器將自動提供一個構(gòu)造函數(shù)陪拘,此構(gòu)造函數(shù)將結(jié)構(gòu)中的每個字段初始化為默認值表中顯示的默認值厂镇。 然而,只有當結(jié)構(gòu)用new實例化時左刽,才會調(diào)用此默認構(gòu)造函數(shù)捺信。對值類型調(diào)用默認構(gòu)造函數(shù)不是必需的。

structA

{staticA()

{

Console.WriteLine("I am A.");

}publicvoidFun()

{

}

}classProgram

{staticvoidMain(string[] args)

{

A a=newA();

a.Fun();//結(jié)構(gòu)的實例成員被引用Console.Read();

}

}

結(jié)果為:I am A.

結(jié)構(gòu)與繼承:

一個結(jié)構(gòu)聲明可以指定實現(xiàn)的接口列表欠痴,但是不能指定基類迄靠。 由于結(jié)構(gòu)不支持類與結(jié)構(gòu)的繼承,所以結(jié)構(gòu)成員的聲明可訪問性不能是?protected?或?protected?internal喇辽。 結(jié)構(gòu)中的函數(shù)成員不能是abstract或virtual掌挚,因而override修飾符只適用于重寫從System.ValueType繼承的方法。 為在設(shè)計編程語言時將結(jié)構(gòu)設(shè)計成無繼承性菩咨?- 其實類的繼承是有相當?shù)某杀镜?——由于繼承性吠式,每個類需要用額外的數(shù)據(jù)空間來存儲“繼承圖”來表示類的傳承歷史, 通俗地說來就是我們?nèi)祟惖募易寮易V抽米,里面存儲著我們的祖宗十八代奇徒,只有這樣我們才知道我們從哪里來的,而家譜肯定是需要額外的空間來存放的缨硝。 大家不要覺得這個存放“繼承圖”的空間很小,如果我們的程序需要用10000個點(Point)來存放游戲中的人物形體數(shù)據(jù)的話罢低, 在一個場景中又有N個人查辩,這個內(nèi)存開銷可不是小數(shù)目了。所以我們可以通過將點(Point)申明成 Struct而不是class來節(jié)約內(nèi)存空間网持。

interfaceITest

{voidFun(intx,inty);

}structA:ITest

{publicvoidFun(intx,inty)//隱式實現(xiàn)接口里的方法{

Console.WriteLine("x={0},y={1}", x, y);

}

}classProgram

{staticvoidMain(string[] args)

{

A a;//結(jié)構(gòu)的實例化可以不使用newa.Fun(1,2);

Console.Read();

}

}//結(jié)果為:x=1,y=2

什么情況下結(jié)構(gòu)的實例化可以不使用new宜岛?

當結(jié)構(gòu)中沒有參數(shù)時,結(jié)構(gòu)的實例化可以不使用new功舀;

當結(jié)構(gòu)中有參數(shù)時萍倡,必須對結(jié)構(gòu)中所有參數(shù)進行初始化后,才能不使用new對結(jié)構(gòu)進行實例化辟汰。

什么時候使用結(jié)構(gòu)列敲?

結(jié)構(gòu)體適合一些小型數(shù)據(jù)結(jié)構(gòu)阱佛,這些數(shù)據(jù)結(jié)構(gòu)包含的數(shù)據(jù)以創(chuàng)建結(jié)構(gòu)后不修改的數(shù)據(jù)為主;

例如:struct類型適于表示Point戴而、Rectangle和Color等輕量對象凑术。

盡管可以將一個點表示為類,但在某些情況下所意,使用結(jié)構(gòu)更有效淮逊。

如果聲明一個10000個Point對象組成的數(shù)組,為了引用每個對象扶踊,則需分配更多內(nèi)存泄鹏;這種情況下,使用結(jié)構(gòu)可以節(jié)約資源秧耗。-

定義的時候不會用到面向?qū)ο蟮囊恍┨匦裕?/p>

結(jié)構(gòu)體在不發(fā)生裝箱拆箱的情況下性能比類類型是高很多的.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末备籽,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绣版,更是在濱河造成了極大的恐慌胶台,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杂抽,死亡現(xiàn)場離奇詭異诈唬,居然都是意外死亡,警方通過查閱死者的電腦和手機缩麸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門铸磅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人杭朱,你說我怎么就攤上這事阅仔。” “怎么了弧械?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵八酒,是天一觀的道長。 經(jīng)常有香客問我刃唐,道長羞迷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任画饥,我火速辦了婚禮衔瓮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抖甘。我一直安慰自己热鞍,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著薇宠,像睡著了一般偷办。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上昼接,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天爽篷,我揣著相機與錄音,去河邊找鬼慢睡。 笑死逐工,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的漂辐。 我是一名探鬼主播泪喊,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼髓涯!你這毒婦竟也來了袒啼?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤纬纪,失蹤者是張志新(化名)和其女友劉穎蚓再,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體包各,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡摘仅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了问畅。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片娃属。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖护姆,靈堂內(nèi)的尸體忽然破棺而出矾端,到底是詐尸還是另有隱情,我是刑警寧澤卵皂,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布秩铆,位于F島的核電站,受9級特大地震影響灯变,放射性物質(zhì)發(fā)生泄漏殴玛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一柒凉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧篓跛,春花似錦膝捞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鲤遥。三九已至,卻和暖如春林艘,著一層夾襖步出監(jiān)牢的瞬間盖奈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工狐援, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留钢坦,地道東北人。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓啥酱,卻偏偏與公主長得像爹凹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子镶殷,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容