<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          c# 誤區(qū)系列(二)

          共 2717字,需瀏覽 6分鐘

           ·

          2020-10-24 02:44

          前言

          繼續(xù)整理誤區(qū)系列,可能會(huì)對(duì)剛?cè)腴T(mén)的新手有些幫助,然后希望有錯(cuò)誤的地方可以指出。


          正文

          關(guān)于泛型方法的確定

          class Person{public void add(T a){   }}

          那么請(qǐng)問(wèn)這個(gè)add 是否是泛型方法。

          初學(xué)者可能認(rèn)為有泛型參數(shù)的就是泛型,其實(shí)不是的。


          這個(gè)是為什么呢?其實(shí)是這樣子的,當(dāng)泛型類(lèi)型確認(rèn)的時(shí)候,那么add 定義的時(shí)候就已經(jīng)確定了類(lèi)型。


          比如說(shuō)Person,那么這個(gè)T就是string,Person 是泛型,但是Person不是。


          當(dāng)T確定是string的時(shí)候,在方法申明的時(shí)候就已經(jīng)是string了,而不存在泛型這個(gè)概念。


          所有泛型的開(kāi)銷(xiāo)沒(méi)有我們想象的這么大,在應(yīng)用中,甚至使用泛型效率更高,不是說(shuō)泛型是優(yōu)化,而是泛型幫我們避免了太多裝箱和拆箱操作。


          比如說(shuō)以前的ArrayList,當(dāng)我們把int 存進(jìn)去,是裝箱,使用int又是拆箱。


          泛型方法是這樣的:

          class Person{public void add(T a,Q b)   {   }}


          在每次調(diào)用add的時(shí)候都必須確認(rèn)Q的類(lèi)型。


          可空類(lèi)型是引用類(lèi)型?

          因?yàn)榭煽疹?lèi)型是可以為空的,那么初學(xué)者可能就認(rèn)為可空類(lèi)型是引用類(lèi)型了。

          其實(shí)可空類(lèi)型是值類(lèi)型,這個(gè)是為什么?看下其中的原理。


          說(shuō)是可空值類(lèi)型,里面包含著一個(gè)判斷位。


          這個(gè)是什么意思呢,比如說(shuō)一個(gè)字節(jié)表示0-255,那么會(huì)多分配一位去判斷這個(gè)字節(jié)是否為空。

          就是多一個(gè)位去判斷是否為空。

          那么這樣我們是不是就可以隨便使用呢?


          從內(nèi)存和cpu的角度來(lái)說(shuō),一個(gè)可空會(huì)增加一位,會(huì)增加內(nèi)存消耗。同樣每次使用的時(shí)候都要判斷是否為null,會(huì)增加cpu負(fù)擔(dān)。


          既然是值類(lèi)型,那么就存在裝箱和拆箱過(guò)程,那么這個(gè)過(guò)程有什么不同嗎?


          裝箱時(shí)檢查是否為null,如果為null則直接返回null,如果不是null則獲取值進(jìn)行裝箱。

          拆箱時(shí)如果不是null,則返回值,否則返回null。



          所以在c# 不能把null 看做是某個(gè)具體的地址,0x00之類(lèi)的,更多的是一個(gè)概念。

          那么問(wèn)題來(lái)了,為什么int 不能為空?或者值類(lèi)型不能為空?


          很多回答是這樣子的,值變量的本身是具體的值。那么難道引用類(lèi)型不是指的具體的地址嗎?


          個(gè)人覺(jué)得是這樣子的,int 類(lèi)型的定義就規(guī)定了多少位為(應(yīng)用程序如果判斷是int的),具有某種穩(wěn)定的結(jié)構(gòu),如果破壞這種結(jié)構(gòu),那么就不是int了。所以int類(lèi)型不能為null,這是int類(lèi)型的定義。


          事件是一種特殊的委托?

          個(gè)人認(rèn)為這句話存在很大的問(wèn)題,是一個(gè)概念性問(wèn)題。

          比如說(shuō),我們說(shuō)正方形是一種特殊的長(zhǎng)方形。


          為什么可以這么說(shuō)呢?來(lái)看一下長(zhǎng)方形的定義。

          長(zhǎng)方形是有一個(gè)角是直角的平行四邊形。


          長(zhǎng)方形的性質(zhì)為:兩條對(duì)角線相等;兩條對(duì)角線互相平分;兩組對(duì)邊分別平行;
          兩組對(duì)邊分別相等;四個(gè)角都是直角;有2條對(duì)稱(chēng)軸(正方形有4條);


          具有不穩(wěn)定性(易變形);長(zhǎng)方形對(duì)角線長(zhǎng)的平方為兩邊長(zhǎng)平方的和;順次連接矩形各邊中點(diǎn)得到的四邊形是菱形。


          從這個(gè)定義中,我們得知長(zhǎng)方形包含了正方形,因?yàn)槠渲虚L(zhǎng)方形并沒(méi)有定義長(zhǎng)和寬不相等啊。


          同樣正方形本身就是長(zhǎng)方形,只是說(shuō)正方形在長(zhǎng)方形的條件下,增加了其他條件。

          綜上所述,是可以這么說(shuō)的。



          但是事件是一種特殊的委托,是真的不能這么講,因?yàn)槭莾煞N完全不同的概念。

          什么是事件?

          1.事件的擁有者

          2.事件成員(事件的本身)

          3.事件響應(yīng)者

          4.事件處理器:本質(zhì)上是一種回調(diào)方法

          5.事件的訂閱:誰(shuí)響應(yīng)誰(shuí)訂閱


          什么是委托?

          委托是一個(gè)類(lèi),它定義了方法的類(lèi)型,使得可以將方法當(dāng)作另一個(gè)方法的參數(shù)來(lái)進(jìn)行傳遞,這種將方法動(dòng)態(tài)地賦給參數(shù)的做法,可以避免在程序中大量使用If-Else(Switch)語(yǔ)句,同時(shí)使得程序具有更好的可擴(kuò)展性。


          你會(huì)發(fā)現(xiàn)這是兩種是不同的概念。那么是如何產(chǎn)生這種誤解的呢?

          看到網(wǎng)上大量流傳著:public delegate void EventHandler(object sender, EventArgs e);


          這只是說(shuō)明委托是事件的一種驅(qū)動(dòng)方式,如果把事件認(rèn)為是一種委托就比較狹隘了,因?yàn)橛行I(yè)務(wù)用到事件,如果想到事件就想到委托,就會(huì)陷入到僵局中,這樣沒(méi)有去從新定義更復(fù)雜的事件。


          可能這樣不好理解,舉一個(gè)例子,比如說(shuō)觀察者模式,c# 中委托作為觀察者例子,但是觀察者和委托沒(méi)有任何直接關(guān)系,難道沒(méi)有委托,觀察者就不存在?


          具體可見(jiàn)觀察者:

          https://www.cnblogs.com/aoximin/p/13726813.html

          datetime 是引用類(lèi)型?

          初學(xué)者看到datetime 有方法就認(rèn)為是引用類(lèi)型,因?yàn)橹殿?lèi)型都更加簡(jiǎn)單,沒(méi)有那么多可操作的方法,然而datetime的確是值類(lèi)型。


          這里涉及到一個(gè)問(wèn)題,那么就是值類(lèi)型的定義上,值類(lèi)型的判斷不是說(shuō)存在的位置,也不是說(shuō)值類(lèi)型沒(méi)有方法,而是指這種類(lèi)型的值是否具有一個(gè)穩(wěn)定的結(jié)構(gòu)(大小等)。


          那么是否值類(lèi)型比引用類(lèi)型性能更好呢?

          這個(gè)肯定不是的。值類(lèi)型(棧上)的優(yōu)點(diǎn)在于,不用垃圾回收,不會(huì)因?yàn)轭?lèi)型標(biāo)識(shí)而產(chǎn)生開(kāi)銷(xiāo),也不用解引用。存儲(chǔ)在堆上的值類(lèi)型,直接和對(duì)象一起回收。


          這里解釋一下,為什么不用垃圾回收,因?yàn)槿绻鹖nt 類(lèi)型不可引用,表示在運(yùn)行系統(tǒng)中沒(méi)有其地址了。再舉個(gè)例子,就是我們磁盤(pán)清空了,格式化了,數(shù)據(jù)還在,只是在它的運(yùn)行系統(tǒng)中不認(rèn)為其存在有效數(shù)據(jù)。


          所以說(shuō)為什么值類(lèi)型在創(chuàng)建的時(shí)候要清空分配的地址,是在使用的時(shí)候抹除的。


          引用類(lèi)型的有點(diǎn)在于傳遞,因?yàn)橐妙?lèi)型不用復(fù)制整個(gè)地址塊,只需要復(fù)制堆上對(duì)象的指定位置,32位是4個(gè)字節(jié),64是8個(gè)字節(jié)。


          對(duì)象在c# 中默認(rèn)傳遞是引用傳遞的


          這個(gè)問(wèn)題涉及于,這樣一個(gè)場(chǎng)景。

          void doSomething(Student student){}doSomething(a);


          那么問(wèn)題是student是如何賦值的過(guò)程?是將這個(gè)a對(duì)象賦值給他嗎?

          這個(gè)問(wèn)題就是student這個(gè)變量存在堆上還是棧上了?student的值本身是地址,而地址是固定的類(lèi)型(32位4個(gè)字節(jié),64位8個(gè)字節(jié)),其實(shí)是值類(lèi)型。


          傳遞過(guò)程是將a的值傳遞給student,之所以叫做引用類(lèi)型,是他們的值指向的位置。

          那么問(wèn)題來(lái)了:

          void doSomething(Student student){}doSomething(null);

          那么student是否有值?也是有值的,指向就是null,在引用類(lèi)型中它本身就是一個(gè)對(duì)象。


          結(jié)

          未完,續(xù)。


          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆av影院 | 国产午夜精品一区二区三区四区 | 欧美在线视频播放 | 大香蕉75| 九七精品视频在线观看 |