<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      C#語(yǔ)言struct結(jié)構(gòu)體適用場(chǎng)景和注意事項(xiàng)

      在C#語(yǔ)言中struct結(jié)構(gòu)體和class之間的區(qū)別主要是值類(lèi)型和引用類(lèi)型的區(qū)別,但實(shí)際上如果使用不當(dāng)是非常要命的。從Win32時(shí)代過(guò)來(lái)的人對(duì)于struct一點(diǎn)不感覺(jué)陌生,但是卻反而忽略了一些基本問(wèn)題。我們知道C#在涉及到本地代碼的地方大量使用了struct,很大程度上是為了移植代碼的需要。很多時(shí)候,感覺(jué)結(jié)構(gòu)比較簡(jiǎn)單的類(lèi)改為struct可能會(huì)提高性能,但這種感覺(jué)在絕大多數(shù)情況下其實(shí)是錯(cuò)誤的。那么我們自己在編寫(xiě)代碼的時(shí)候究竟在什么情況下適合定義struct而不是class呢?

      選用struct的原則

      通過(guò)閱讀微軟的技術(shù)文章Choosing Between Class and Struct,可以了解到選擇使用struct的一些準(zhǔn)則。

      考慮 定義struct而非class,如果類(lèi)型的實(shí)例很小而且通常存活期都很短或者一般都嵌入到其它對(duì)象中使用

      避免 定義struct除非類(lèi)型滿(mǎn)足以下全部特征:

      • 邏輯上表達(dá)了一個(gè)單一值,類(lèi)似基本數(shù)據(jù)類(lèi)型(int, double)
      • 實(shí)例大小低于16字節(jié)
      • 不可改變
      • 不會(huì)被頻繁裝箱

      個(gè)人總結(jié)了一些使用場(chǎng)景和注意的地方。

      • 對(duì)于初學(xué)者或者一般情況,請(qǐng)使用class不要考慮struct。當(dāng)程序需要考慮性能而進(jìn)行優(yōu)化的階段再考慮struct問(wèn)題
      • 定義struct時(shí),盡量作為私有類(lèi)型或內(nèi)部類(lèi)型,不要公開(kāi)
      • struct的屬性不要定義公開(kāi)的set方法,也就是不可改變
      • 使用struct管理非托管資源時(shí),定義Free方法,使用時(shí)一定要在恰當(dāng)時(shí)機(jī)調(diào)用Free。千萬(wàn)不要想著去實(shí)現(xiàn)IDisposable接口。如果覺(jué)得不安全,那就改用class吧!
      • 如果需要調(diào)用本地代碼而迫不得已,才可以無(wú)視其它原則而選用struct

      struct的性能

      選用struct可以在一些特定條件下改善程序性能,但請(qǐng)注意,沒(méi)有“銀彈”能夠在所有情況下解決所有問(wèn)題。

      struct一般用于一些結(jié)構(gòu)簡(jiǎn)單,可以用單一值概念描述的類(lèi)型。同時(shí),類(lèi)型的存活期應(yīng)該不會(huì)太長(zhǎng)。struct無(wú)需創(chuàng)建即可使用,也沒(méi)有垃圾回收問(wèn)題。struct壓根就不在GC堆內(nèi)存中分配,而是直接在棧內(nèi)存中分配。在使用struct時(shí)都會(huì)復(fù)制到當(dāng)前棧內(nèi)存中,就像其它值類(lèi)型一樣。以上這些特性只能說(shuō)和class在使用上會(huì)有差異,需要注意。但說(shuō)不上是優(yōu)點(diǎn)還是缺點(diǎn),取決于用法和具體情況。另外,struct不存在并發(fā)競(jìng)爭(zhēng)問(wèn)題,多線(xiàn)程安全,這應(yīng)該算是優(yōu)點(diǎn)了。

      一種已知情況可以用struct來(lái)優(yōu)化程序,就是struct類(lèi)型的數(shù)組(注意是數(shù)組不是List,至于基于哈希的集合不好說(shuō))。struct數(shù)組在物理上一定是一個(gè)連續(xù)的內(nèi)存塊。如果是引用類(lèi)型,則物理上一般是分配指針來(lái)指向引用的實(shí)例,此時(shí)數(shù)組的內(nèi)存塊不能涵蓋所有要訪(fǎng)問(wèn)的數(shù)據(jù)。而struct數(shù)組在這種情況下所有會(huì)用到的數(shù)據(jù)都在數(shù)組的物理內(nèi)存之中包含,可以直接訪(fǎng)問(wèn)到,無(wú)需通過(guò)GC堆內(nèi)存的對(duì)象引用來(lái)反復(fù)的間接查找。同時(shí),如果實(shí)例數(shù)量非常多時(shí),使用struct數(shù)組還能避免大量分散在GC堆中的對(duì)象實(shí)例,從而減輕GC壓力。這里理想化的認(rèn)為struct的定義中所有字段都是值類(lèi)型的,不包含string等引用類(lèi)型。

      此時(shí),對(duì)struct數(shù)組中的下標(biāo)訪(fǎng)問(wèn)不會(huì)造成復(fù)制(List的下標(biāo)訪(fǎng)問(wèn)則會(huì)),直接內(nèi)存定位效率很高。

      int id = structArray[i].Id;

      注意,struct字段不可變會(huì)很有幫助,如果需要修改字段內(nèi)容,通過(guò)ref方法。
      定義:

      public static void SetId(ref structType target, int value) 
      { 
          target.Id = value; 
      }

      使用:

      SetId(ref structArray[i], 100);

      實(shí)際上很多情況下,struct反而會(huì)拖慢我們的程序。由于值類(lèi)型在使用上的復(fù)制特性,定義一個(gè)龐大的struct在絕大多數(shù)情況下性能會(huì)比引用類(lèi)型要糟糕。因?yàn)槊看问褂玫絪truct時(shí)都會(huì)在棧中復(fù)制一份新實(shí)例,復(fù)制來(lái)復(fù)制去的,如果struct的定義的字段比較多占用很多字節(jié)的話(huà),復(fù)制的成本就會(huì)很高。這也是為什么微軟給出的準(zhǔn)則中有一條:“當(dāng)類(lèi)型定義大于16字節(jié)時(shí)不要選用struct”。

      struct是不可變的!

      首先,從邏輯上,一個(gè)struct描述了一個(gè)單一值,struct的所有公開(kāi)的屬性、字段都應(yīng)該是用于獲取這個(gè)單一值的一些特征的,這從邏輯上就杜絕了可賦值的屬性這樣的定義。

      其次,由于struct是值類(lèi)型,分配在棧內(nèi)存中或者是擁有struct類(lèi)型的引用類(lèi)型對(duì)象中,任何時(shí)候?qū)truct的訪(fǎng)問(wèn)都會(huì)訪(fǎng)問(wèn)原始struct的副本,因此對(duì)struct屬性的修改實(shí)際上是在修改原始struct的副本。除非你將修改后的struct實(shí)例重新賦值回去,否則原始struct是不會(huì)改變。這一特性同樣適用于函數(shù)方法的參數(shù)是struct的情況。

      當(dāng)然,要直接改變?cè)約truct也是有辦法的,那就是使用ref類(lèi)型的的方法參數(shù)來(lái)直接改變?cè)贾怠5@就需要定義一個(gè)專(zhuān)門(mén)的方法,通過(guò)struct的屬性來(lái)訪(fǎng)問(wèn)時(shí)仍然會(huì)有上述問(wèn)題。

      用struct管理本地代碼

      用struct管理本地代碼時(shí),注意定義釋放方法,而使用時(shí)要在恰當(dāng)時(shí)機(jī)去明確調(diào)用釋放方法。

      struct沒(méi)有明確的無(wú)參構(gòu)造方法,也沒(méi)有析構(gòu)方法。這是因?yàn)閟truct本身就是一份棧內(nèi)存,無(wú)需new新的實(shí)例,也無(wú)需去釋放。

      但如果struct內(nèi)部使用了本地資源,這時(shí)本地資源的釋放就成了問(wèn)題。對(duì)于object的class類(lèi)型,我們可以定義實(shí)現(xiàn)IDisposable接口,在使用時(shí)用using代碼塊來(lái)創(chuàng)建實(shí)例。但是對(duì)于struct來(lái)說(shuō),千萬(wàn)不要。因?yàn)樵趗sing的時(shí)候使用的是struct的副本,而內(nèi)存中可能存在很多很多struct的副本。這種情況下,Dispose的邏輯應(yīng)當(dāng)非常可靠才能避免重復(fù)釋放的問(wèn)題。

      實(shí)際上,用struct來(lái)管理本地資源的情況一定要將struct定義為私有或內(nèi)部,作為一個(gè)公開(kāi)類(lèi)型的內(nèi)部實(shí)現(xiàn)。這樣可以保證所有使用的實(shí)例都能夠被干凈釋放,避免內(nèi)存泄漏。

      posted @ 2016-08-01 00:03  熾火  閱讀(8350)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 精品国产午夜福利理论片| 日本久久久久亚洲中字幕| 色婷婷日日躁夜夜躁| 一本色道婷婷久久欧美| 玩弄漂亮少妇高潮白浆| 人成午夜免费视频无码| 国色精品卡一卡2卡3卡4卡在线 | 麻豆一区二区三区蜜桃免费| 欧洲一区二区中文字幕| 亚洲日韩av在线观看| 欧美熟妇xxxxx欧美老妇不卡| 激情久久av一区二区三区| 午夜福利影院不卡影院| 亚洲一区二区约美女探花| 国产偷国产偷亚洲高清人| 四虎国产精品成人免费久久| 偷拍专区一区二区三区| 国产一级小视频| 无码精品人妻一区二区三区老牛| 国产精品免费看久久久| 国产亚洲精品一区二区不卡 | 91亚洲国产三上悠亚在线播放| 久久99精品久久久久久青青| 国内揄拍国内精品人妻久久| 被灌满精子的少妇视频| 人妻系列中文字幕精品| 久久三级中文欧大战字幕| 欧美猛少妇色xxxxx| 成人精品自拍视频免费看| 黄又色又污又爽又高潮| 午夜dv内射一区二区| 男女啪啪高清无遮挡免费| 午夜免费福利小电影| 在线观看特色大片免费视频| 国产偷拍自拍视频在线观看| 国产综合久久99久久| av男人的天堂在线观看国产| 18禁精品一区二区三区| 在线 欧美 中文 亚洲 精品| 衡南县| 最新国产AV最新国产在钱|