C基礎(chǔ)知識(需要特別注意的知識點)_第1頁
C基礎(chǔ)知識(需要特別注意的知識點)_第2頁
C基礎(chǔ)知識(需要特別注意的知識點)_第3頁
C基礎(chǔ)知識(需要特別注意的知識點)_第4頁
C基礎(chǔ)知識(需要特別注意的知識點)_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

《C#4.0本質(zhì)論》學(xué)習(xí)筆記

值類型和引用類型的區(qū)別

值類型引用類型

1.直接包含值,變量引用的位置就是值存儲是對一個內(nèi)存位置的引用(內(nèi)存地

在內(nèi)存中實際存儲的位置。址),要去那個位置才能找到真正的數(shù)據(jù)

2,數(shù)據(jù)存儲在棧的內(nèi)存區(qū)域中數(shù)據(jù)存儲在堆的內(nèi)存區(qū)域

3.在編譯時確定內(nèi)存量在運行時,從變量中讀取內(nèi)存地址,然后

到指定內(nèi)存地址中讀取數(shù)據(jù)。

4.復(fù)制數(shù)據(jù)的一個副本只復(fù)制數(shù)據(jù)的地址

5.將new用于值類型,會使用默認值初new,調(diào)用構(gòu)造函數(shù)生成一個對象(實例)

始化內(nèi)存

二、裝箱與拆箱

1.裝箱:將一個值類型轉(zhuǎn)換成一個引用類型

1)首先在堆中分配好內(nèi)存;

2)一次內(nèi)存復(fù)制:棧上的值類型數(shù)據(jù)復(fù)制到堆上分配好的位置;

3)對象或接口引用得到更新,指向堆上的位置。

2.拆箱:將一個引用類型轉(zhuǎn)換為值類型

3,裝箱頻繁發(fā)生,會大幅影響性能;

4.不允許在lock()語句中使用值類型。

三、String與StringBuilder

1.String對象稱為不可變的(只讀),因為一旦創(chuàng)建了該對象,就不能修改該對象的

2.StringBuilder此類表示值為可變字符序列的類似字符串的對象

3.String對象串聯(lián)操作總是用現(xiàn)有字符串和新數(shù)據(jù)創(chuàng)建新的對象.StringBuilder對象

維護一個緩沖區(qū),以便容納新數(shù)據(jù)的串聯(lián)。如果有足夠的空間,新數(shù)據(jù)將被追加到

緩沖區(qū)的末尾;否則,將分配一個新的、更大的緩沖區(qū),原始緩沖區(qū)中的數(shù)據(jù)被復(fù)

制到新的緩沖區(qū),然后將新數(shù)據(jù)追加到新的緩沖區(qū)。

4.String或StringBuilder對象的串聯(lián)操作的性能取決于內(nèi)存分配的發(fā)生頻率。String

串聯(lián)操作每次都分配內(nèi)存,而StringBuilder串聯(lián)操作僅當StringBuilder對象緩沖

區(qū)太小而無法容納新數(shù)據(jù)時才分配內(nèi)存。因此,如果串聯(lián)固定數(shù)量的String對象,

則String類更適合串聯(lián)操作。這種情況下,編譯器甚至?xí)⒏鱾€串聯(lián)操作組合到

一個操作中。如果串聯(lián)任意數(shù)量的字符串,則StringBuilder對象更適合串聯(lián)操作;

例如,某個循環(huán)對用戶輸入的任意數(shù)量的字符串進行串聯(lián)。

四、?和??的使用

1.可空修飾符?:為了聲明可以存null的值類型變量。int?x=null;

2.使用??運算符分配默認值:expressionl??expression2.檢查第一個表達式是否為

null,如果為null,則返回第二個表達式。

3.當前值為空的可以為null的類型被賦值給非空類型時將應(yīng)用該默認值,如int?x=

null;inty=x??-l;o

三、const和readonly

1.const:

1)既然用于修飾字段,又可以修飾局部變量;

2)是在編譯時確定的值,不可以在運行時改變;

3)自動成為靜態(tài)字段,不能顯式聲明為static

2.readonly:

1)只能用于字段(不能用于局部變量),

2)指出字段值只能從構(gòu)造函數(shù)中更改,或者直接在聲明時指定。一一可以在運行

時賦值;

3)readony字段既可以是實例字段,也可以是靜態(tài)字段.

四、靜態(tài)成員和實例成員

1.靜態(tài)字段:主要存儲的是對于類的數(shù)據(jù),能由多個實例共享,需要使用static關(guān)鍵

2.實例字段:存儲的是與對象關(guān)聯(lián)的數(shù)據(jù),只能從類的一個實例(對象)中訪問實例

字段。

3.靜態(tài)方法:不能直接訪問一個類中的實例字段,必須獲取類的一個實例,才能調(diào)用

任一實例成員(方法或字段)。

4.實例方法:將需要訪問實例數(shù)據(jù)的方法聲明為實例方法。

5.靜態(tài)構(gòu)造函數(shù):用來對類(而不是類實例)進行初始化。

運行時會在“訪問類的一個靜態(tài)方法或者字段時”自動調(diào)用靜態(tài)構(gòu)造函數(shù)。

6.靜態(tài)類:不包含任何實例字段(或方法),聲明時用static關(guān)鍵字。不能被實例化,

不能被繼承。

五、繼承:對一個現(xiàn)有的類型進行擴展,以包含附加的成員或?qū)崿F(xiàn)對基類成員的定制。

1.protected訪問修飾符:在基類中定義只有派生類才能訪問的成員。

規(guī)則:要從一個派生類中訪問一個受保護的成員,必須在編譯時確定受保護的成員

是派生類(或者它的某個子類)的一個實例。

2.C#是一種單一繼承的語言,一個類不能直接從兩個類派生。

3.可以使用聚合解決多重繼承的問題

4.使用sealed修飾符,實現(xiàn)密封類(不能被繼承)

5.C#支持重寫實例方法和屬性,但不支持重寫字段或者任何靜態(tài)成員。

1)在基類中使用virtual修飾符標記每一個需要重寫的成員,

2)在派生類中,用override進行修飾。C#要求重寫方法顯式地使用override關(guān)鍵

字。

3)重寫一個成員時,會造成“運行時”調(diào)用派生得最遠的實現(xiàn)。

4)new修飾符:在基類面前隱藏了派生類的重新聲明的成員。

6.抽象類:

1)僅供派生的類,不能被實例化。

2)包含抽象成員:不具有實現(xiàn)的一個方法或?qū)傩?,強制所有派生類提供實現(xiàn)。

7.多態(tài)性:同一個簽名可以有多個實現(xiàn)。

1)抽象成員是實現(xiàn)多態(tài)性的一個手段:基類指定方法的簽名,派生類提供具體的

實現(xiàn);

2)可以利用多態(tài)性:調(diào)用基類的方法,當方法具體由派生類實現(xiàn)。

8.is和as運算符

1)is運算符驗證基礎(chǔ)類型

2)使用as運算符進行轉(zhuǎn)換:將對象轉(zhuǎn)換為一個特定的數(shù)據(jù)類型,若源類型不是固

有的目標類型,as運算符會將null值賦給目標。

六、接口

1.對接口的理解:

1)接口定義了一系列成員,不包含任何實現(xiàn),由繼承該接口的類實現(xiàn);

2)接口實現(xiàn)關(guān)系是一個“能做”關(guān)系:類“能做”接口要求的事情;

3)接口定義了一個“契約”:實現(xiàn)接口的類會使用與被實現(xiàn)的接口相同的簽名來定

義方法。

4)接口的宗旨是:定義由多個類共同遵守的一個契約,所有成員都自動定義為

publico

5)C#不允許為接口成員使用訪問修飾符。

6)通過接口可以實現(xiàn)多態(tài)性;

7)不能被實例化,不能使用new關(guān)鍵字來創(chuàng)建一個接口。

2.接口實現(xiàn):

1)一個類只能從一個基類派生,但可以實現(xiàn)多個接口;

2)顯式實現(xiàn):為了聲明一個顯式接口成員實現(xiàn),需要在成員名之前附加接口名前

綴。

String[]IListable.ColumnValues

通過接口本身來調(diào)用它一一將對象轉(zhuǎn)型為接口;

\/alues=((IListable)contactl).Columnvalues

3)隱式實現(xiàn):類成員的簽名與接口成員的簽名相符。

調(diào)用時不需要轉(zhuǎn)型,可以直接調(diào)用。

4)成員若是核心的類功能,則隱式實現(xiàn);

5)假如一個成員的用途在實現(xiàn)類中不是很明確,就考慮使用一個顯式的實現(xiàn);

6)已經(jīng)有一個同名的類成員,則可以使用顯式實現(xiàn)。

3.接口繼承:

1)一個接口可以從另一個接口派生,派生的接口將繼承“基接口”的所有成員;

2)在用于顯式接口成員實現(xiàn)的一個完全限定的接口成員名稱中,必須引用最初聲

明它的那個接口的名稱;

3)繼承:接口代表一份契約,而一份契約可指定另一份契約也必須遵守的條款。

4)通過接口可以實現(xiàn)多重繼承。

4.接口與類的比較

抽象類接口

僅供派生的類,不能被實例化不能實例化

定義了基類必須實現(xiàn)的抽象成員簽名接口的所有成員要在基類中實現(xiàn)

可以包含存儲在字段中的數(shù)據(jù)不能存儲任何數(shù)據(jù)。只能在派生類中指

定字段。解決這個問題的辦法,是在接

口中定義屬性,但不能包括實現(xiàn)。

擴展性比接口好,不會破壞任何版本兼用更多的成員來擴展接口,會破壞版本

容性。在抽象類中,你可以添加附加的兼容性。(只能再創(chuàng)建一個接口,該接口

非抽象成員,它們可以由所有派生類繼可以從原始接口派生)

七、重寫Equals()

1.“對象同一性”和“相等的對象值”

1)對象同一性:兩個引用,引用的是同一個實例;

2)相等的對象值:兩個引用,引用不同的實例,但兩個對象實例值是相等的。

3)只有引用類型才可能引用相等,值類型不可能引用相等(ReferenceEquals()

對值類型進行了裝箱,由于每一個實參都被裝到棧上的不同位置)。

2.實現(xiàn)Equals。:

1)檢查是否為null;

2)如果是引用類型,就檢查引用是否相等;(ReferenceEquals()方法來判斷引用

是否相等)

3)檢查數(shù)據(jù)類型是否相等;

4)調(diào)用一個指定了具體類型的輔助方法,它能將操作數(shù)視為要比較的類型,而

不是一個對象;

5)可能要檢查散列碼是否相等。(相等的兩個對象,不可能散列碼不同)

6)如果基類重寫了Equals(),就檢查base.Equals。;

7)比較每一個標識字段,判斷是否相等;

8)重寫GetHashCode()。

9)重寫==和!=運算符。

八、垃圾回收與資源清理

1.垃圾回收內(nèi)存

1)“運行時”的一個核心功能:回收不再被引用的對象所占用的內(nèi)存。

2)垃圾回收器只負責回收內(nèi)存,不處理其他資源,比如數(shù)據(jù)庫連接、句柄(文

件、窗口等)、網(wǎng)絡(luò)端口以及硬件設(shè)備(比如串口)等;

3)垃圾回收器處理的是引用對象,而且只回收堆上的內(nèi)存;

2.終結(jié)器釋放資源

1)終結(jié)器:允許程序員編寫代碼來清理一個類的資源;

2)由垃圾回收器負責為一個對象實例調(diào)用終結(jié)器;

3)終結(jié)器會在上一次使用對象之后,并在應(yīng)用程序關(guān)閉之前的某個時間運行。

4)終結(jié)器不允許傳遞任何參數(shù),不能被重載,不能被顯式調(diào)用,不允許使用訪

問修飾符;

5)終結(jié)器負責釋放像數(shù)據(jù)庫連接和文件句柄這樣的資源,不負責回收內(nèi)存(回

收內(nèi)存是由垃圾回收器完成)

6)避免在終結(jié)器中出現(xiàn)異常,比如采用空值檢查。

3.使用using語句進行確定性終結(jié):

1)[Disposable接口用一個名為Dispose。的方法釋放當前消耗的資源;

2)using語句在對象離開作用域時自動調(diào)用Dispose。方法釋放資源。

4.垃圾回收和終結(jié)

1)f-reachable隊列(終結(jié)隊列):是準備好進行垃圾回收,同時實現(xiàn)終結(jié)的所

有對象的一個列表;

2)假如一個對象有終結(jié)器,那么“運行時”只有在對象的終結(jié)方法被調(diào)用之后,

才能對這個對象執(zhí)行垃圾回收;

3)f-reachable隊列是一個“引用”列表,一個對象只有在它的終結(jié)方法得到調(diào)

用,而且對象引用從f-reachable隊列中刪除之后,才會成為“垃圾”。

九、泛型

1.泛型類型概述:

1)利用泛型,可以在聲明變量時創(chuàng)建用來處理特定類型的特殊數(shù)據(jù)結(jié)構(gòu);

2)參數(shù)化類型,使特定泛型類型的每個變量都有相同的內(nèi)部算法;

3)聲明泛型類:

publicclassStack<T>

privateT[]_ltems;

publicvoidPush(Tdata)

PublicTPop()

}

2.泛型的優(yōu)點:

1)提供了一個強類型的編程模型:確保在參數(shù)化的類中,只有成員明確希望的

數(shù)據(jù)類型才可以使用;

2)為泛型類成員使用值類型,不再造成到object的強制轉(zhuǎn)換,它們不再需要裝

箱操作;

3)性能得到了提高:不再需要從。bject的強制轉(zhuǎn)換,從而避免了類型檢查;不

再需要為值類型執(zhí)行裝箱操作

4)由于避免了裝箱,因此減少了堆上的內(nèi)存的消耗;

3.泛型接口:

1)聲明一個泛型接口:

InterfaceIPair<T>

TFirst{get;set;}

TSecond{get;set}

2)使用泛型接口,就可以避免執(zhí)行轉(zhuǎn)型,因為參數(shù)化的接口能實現(xiàn)更強的編譯

時綁定;

3)在一個類中多次實現(xiàn)相同的接口:可以使用不同的類型參數(shù)來多次實現(xiàn)同一

個接口。

4.多個類型參數(shù):

1)泛型類型可以使用任意數(shù)量的類型參數(shù);

2)聲明:

InterfaceIPair<TFirstJSecond>

(

TFirstFirst{get;set;}

TSecondSecond{get;set}

}

PublicstructPair<TFirst,TSecond>:IPair<TFirst/TSecond>

(

PublicPair(TFirstfirst,TSecondsecond)

(

_First=first;

__Second=second;

)

5.約束

1)泛型允許為類型參數(shù)定義約束。這些約束強迫類型遵守各種規(guī)則;

2)約束聲明了泛型要求的類型參數(shù)的特征.

3)為了聲明一個約束,需要使用where關(guān)鍵字,后跟一對“參數(shù):要求”;其中,

“參數(shù)”必須是泛型類型中定義的一個參數(shù),而“要求”用于限制類型從中

派生的類或接口,或者限制必須存在一個默認構(gòu)造器,或者限制使用一個引

用/值類型約束。

4)接口約束:為了規(guī)定某個數(shù)據(jù)類型是必須實現(xiàn)某個接口,需要聲明一個接口

約束。不需要執(zhí)行轉(zhuǎn)型,就可以調(diào)用一個顯式的接口成員實現(xiàn)。

聲明一個接口約束:

publicclassBinaryTree<T>

whereT:System.lComparable<T>

PublicPair<BinaryTree<T?SubItems

{

get{return_Subltems;}

set

IComparable<T>first;

First=value.First.Item;

)

5)基類約束:將構(gòu)建的類型限制為一個特定的類派生。

6)struct約束:將類型參數(shù)限制為一個值類型;

7)class約束:將類型參數(shù)限制為一個引用類型。

8)多個約束:對于任何給定的類型參數(shù),都可以指定任意數(shù)量的接口作為約束,

但基類約束只能指定一個,因為一個類可以實現(xiàn)任意數(shù)量的接口,但肯定只

能從一個類繼承。

publicclassEntityDictionary<Tkey,Tvalue>

:Dictionary<TKey,TValue>

whereTKey:IComparable<TKey>,IFormattable〃多個約束接口

whereTValue:EntityBase//一個基類約束

9)構(gòu)造器約束:可以在指定了其他所有約束之后添加new(),指定類型參數(shù)必

須有一個默認構(gòu)造器。

10)繼承約束:約束可以由一個派生類繼承,但必須在派生類中顯式地指定這

些約束。

6.泛型方法

1)即使包容類不是泛型類,或者方法包含的類型參數(shù)不在泛型類的類型參數(shù)列

表中,也依然使用泛型的方法;

2)為了定義泛型方法,需要緊接在方法名之后添加類型參數(shù)語法;

7.協(xié)變性和逆變性

1)協(xié)變性:將一個較具體的類型賦給較泛化的類型。

2)逆變性:將較泛化的類型賦給較具體的類型;

3)在C#4.0中使用out類型參數(shù)修飾符允許協(xié)變性;

4)在C#4.0中使用int類型參數(shù)修飾符允許逆變性;

8.泛型的內(nèi)部機制:

1)基于值類型的泛型的實例化:“運行時”會為每個新的參數(shù)值類型創(chuàng)建新的具

體化泛型類型。

2)基于引用類型的泛型的實例化:使用一個引用類型作為類型參數(shù)來首次構(gòu)造

一個泛型類型時,“運行時”會創(chuàng)建一個具體化的泛型類型,并在CIL代碼中

用object引用替換類型參數(shù)。以后,“運行時”都會重用以前生成好的泛型類

型的版本一一即使新的引用類型與第一次使用的引用類型不同。

十、委托、Lambda表達式

1.委托:將方法作為對象封裝起來,允許在“運行時”間接地綁定一個方法調(diào)用;

2.所有委托類型都間接從System.Delegate派生,但System.Delegate不能顯式的成為

一個基類;

3.聲明委托數(shù)據(jù)類型:

PublicdelegateboolComparisonHandler(intfirst,intsecond);

4.實例化委托:需要和委托類型自身的簽名對應(yīng)的一個方法(相同的參數(shù)及參數(shù)類型、

相同的返回值);

classDelegateSample

publicdelegateboolComparisonllanlder(intfirst,intsecond);

publicstaticvoidBubbleSort(int[]items,Comparisonllanlder

comparisonMethod)

(

inti,j,temp;

for(i=items.Length-1;i>=0;i-)

(

for(j=1;j<=i;j++)

(

if(comparisonMethod(items[j-1],items[j]))

(

temp=items[j-1];

items[j-1]=items[j];

items[j]=temp;

)

)

)

}

publicstaticboolGreaterThan(intfirst,intsecond)

(

returnfirst>second;

)

staticvoidMain(string[]args)

(

inti;

int[]items=newint[5];

for(i=0;i<items.Length;i++)

(

Console.Write(/zEnteraninteger:");

items[i]=int.Parse(Console.ReadLineO);

}

BubbleSort(items,GreaterThan);

for(i=0;i<items.Length;i++)

(

Console.WriteLine(items[i]);

)

)

)

5.匿名方法:

1)所謂匿名方法,就是沒有實際方法聲明的委托實例,它們的定義是直接內(nèi)嵌

在代碼中;

2)BubbleSort(items,

delegate(intfirst,intsecond)

returnfirst>second;

6.系統(tǒng)定義的委托:Funco

1)在C#3.0中,存在一系列名為“Action”和“Func”的泛型委托;

2)System.Action代表無返回類型的委托;

3)System.Func代表有返回類型的委托;

4)Func的最后一個類型參數(shù)總是委托的返回類型,在它之前的類型參數(shù)則依次

對應(yīng)于委托參數(shù)的類型;

5)可以用一個Func泛型委托來代替一個顯式定義的委托。ComparisonHandler

可以用Func<int,int,bool>來代替

7.Lambda表達式

1)Lambda表達式分為:語句Lambda和表達式Lambda;

2)Lambda運算符―,可以理解成“用于”;

3)使用語句Lambda來傳遞委托:

BubbleSort(items,

(intfirst,intsecond)

returnfirst>second;

4)C#要求用一對圓括號來封閉Lambda表達式的參數(shù)列表,不管是否指定了這

些參數(shù)的數(shù)據(jù)類型;

5)當編譯器能判斷出數(shù)據(jù)類型,而且只有一個輸入?yún)?shù)的時候,語句Lambda

可以帶圓括號;

IEnumerable<Process>

processes=Process.GetProcesses().Where(process=>{return

process.WorkingSet64>2A30;});

6)語句Lambda含有一個語句塊,所以可以包含零個或者更多的語句,而表達

式Lambda只有一個表達式,沒有語句塊;此時將Lambda運算符理解成“滿

足……條件";

BubbleSort(items,(first,second)=>first<second);

〃理解成first和second滿足first小于second的條件

7)Lambda表達式(和匿名方法)并非CLR內(nèi)部的固有構(gòu)造,它們的實現(xiàn)是由

C#編譯器在編譯時生成的。

8)persons.Where(person=>person.Name.Tollpper()==//INIGOMONTOYA");

假定persons是一個Person數(shù)組,編譯器將Lambda表達式編譯成一個

Func<person,bool>委托類型,然后將委托實例傳給Where。方法。

9)表達式樹:如果一種Lambda表達式代表的是與表達式有關(guān)的數(shù)據(jù),而不是

編譯好的代碼,這種Lambda表達式就是“表達式樹&

10)表達式樹轉(zhuǎn)換成的數(shù)據(jù)是一個對象圖,它由

System.Linq.Expressions.Expression表示。

11)Lambda表達式和表達式樹的比較:

表達式的語法都會在編譯時進行完整的語義分析驗證;但是,Lambda表達

式在CIL中被編譯成一個委托,而表達式樹被編譯成

System.Linq.Expressions.Expression類型的一個數(shù)據(jù)結(jié)構(gòu)。

-一、事件

1.多播委托:一個委托變量可以引用一系列委托,在這一系列委托中,每個委托

都順序指向一個后續(xù)的委托,從而形成了一個委托鏈。

2.使用多播委托來編碼Observer模式(又叫publish-subscribe模式):

1)定義訂閱者方法:參數(shù)和返回類型必須和來自發(fā)布者類的委托匹配

2)定義發(fā)布者:只需一個委托字段,就可以存儲所有的訂閱者

3)連接發(fā)布者和訂閱者;

4、調(diào)坦委托:當發(fā)布者中的屬性每次發(fā)生變化時,向訂閱者通知變化;

//callsubscribers

OnTemperatureChange(value);〃將溫度的變化發(fā)給多個訂

閱值cooler和heater對象

5)檢查空值:調(diào)用一個委托之前,要檢查它的值是不是空值;

6)將運算符應(yīng)用于委托會返回一個新實例;

7)委托運算符:+二,獲取第一個委托,并將第二個委托添加到委托鏈中,使一

個委托指向下一個委托。第一個委托的方法調(diào)用之后,它會調(diào)用第二個委托。

8)+,?,?=,+二運算符,在內(nèi)部都是使用靜態(tài)方法System.Delegate.Combine()

和System.Delegate.Remove。來實現(xiàn)的。

9)順序調(diào)用

10)例子:

〃訂閱者

classCoo]er

privatefloatTemperature;

publicfloatTemperature

get{return_Temperature;}

set{_Temperature=value;}

}一

publicCooler(floattemperature)

Temperature-temperature;

publicvoidOnTemperatureChanged(floatnewTemperature)

if(newTemperature>Temperature)

System..WriteLine(''Cooler:0nz/);

)

else

System..WriteLine(''Cooler:Offz,);

〃訂閱者2

ccl{assH(';i:('L!-

privatefloat_Temperature;

publicfloatTemperature

get{returnTemperature;}

set{_Temperaturevalue;}

)

publicHeater(floattemperature)

Temperature=temperature;

)

publicvoidOnTemperatureChanged(floatnewTemperature)

if(newTemperature<Temperature)

System..WriteLine("Cooler:On");

System..WriteLine("Cooler:Off");

〃定義發(fā)布者

classThpri!?,二

publicdelegatevoid/(floatnewTemperature);

//definetheeventpublisher

publicOnTemperatureChange

{

get{returnOnTemperatureChange;}

set{0nTemperatureChange=value;}

private__OnTemperatureChange;

publicfloatCurrentTemperature

get{returnCurrentTemperature;}

if(value!二CurrentTemperature)

_CurrentTemperature=value;

〃檢查空值

localOnChange二

OnTemperatureChange;

if(localOnChange!=null)

OnTemperatureChange(value);〃將溫度的變化發(fā)給多個訂

閱值cooler和heater對象

)

)

)

privatefloat_CurrentTemperature;

}

〃連接發(fā)布者和訂閱者

classProg;din

{

staticvoidMain(string[]args)

i‘Hthermostat=newi,i;ii();

lleatcheater=newH-;itoi(60);

Coolcooler=new((80);

stringtemperature;

thermostat.OnTemperatureChange+=heater.OnTemperatureChanged;

thermostat.OnTemperatureChange+=cooler.OnTemperatureChanged;

Consu.Write(/zEntertemperature:,z);

temperature=Console.ReadLineO;

thermostat.CurrentTemperature=int.Parse(temperature);

(⑴z,.ReadLineO;

)

3.事件

1)事件的作用:

封裝訂閱(使用event關(guān)鍵字,避免不小心取消了其他訂閱者),

封裝發(fā)布(只有包容類才能觸發(fā)一個事件通知);

2)事件的編碼規(guī)范:第一個參數(shù)sender是object類型的,它包含對調(diào)用委托

的那個對象的一個引用,第二個參數(shù)是System.EventArgs類型的(或者是從

System.EventArgs派生,但包含了事件附加數(shù)據(jù)的其他類型)。

3)泛型和委托:使用泛型,就可以在多個位置使用相同的委托數(shù)據(jù)類型,并在

支持多個不同的參數(shù)類型的同時保持強類型;

4)聲明泛型委托類型:publicdelegatevoidEventHandler<T>(objectsenderje)

whereT:EventArgs;

使用EventHanlder<T>,任何類如果需要一個特定的sender-EventArgs模式,

都不必聲明它自己的委托定義。相反,它們可以共享同一個委托。

5)

十二、集合、Linq查詢

1.匿名類型:

1)完全由C#編譯器來實現(xiàn)的,而不會在“運行時”內(nèi)有顯式實現(xiàn);

2)當編譯器遇到匿名類型的語法時,會自動生成一個CIL類,其屬性和在匿

名類型聲明中命名的值和數(shù)據(jù)類型是對應(yīng)的;

3)使用匿名類型的隱式局部變量:varpatentl=new{Title=,,Hello/,,

Value="World"};

4)是強類型的。

5)匿名類型是不可變的:一經(jīng)實例化,再更改它的某個屬性,就會造成編譯

錯誤;

6)類型兼容:在同一程序集中,兩個匿名類型類型兼容的必要條件為屬性名、

數(shù)據(jù)類型和屬性順序都完全匹配。

2.隱式類型的局部變量:

1)遇到一個隱式類型的變量時,編譯器會首先分析右側(cè)的表達式,確定它的

類型,根據(jù)所賦的數(shù)據(jù)類型來確定該變量的數(shù)據(jù)類型;

2)遇到顯式類型的局部變量時(而且聲明的同時已賦值),比如string

s="Hello";編譯器首先會根據(jù)左側(cè)明確聲明的類型來確定s的類型,然后分

析右側(cè)的表達式,驗證右側(cè)的表達式是否適合賦給那個類型的變量;

3.集合初始化器:

1)使用集合初始化器,程序員可以采取和數(shù)組聲明相似的方式,在一個集合

的實例化期間用一套初始的成員來構(gòu)造這個集合。

4.foreach和IEnumerable<T>

1)System.Collections.Generic.lEnumerator<T>和非泛型

System.Collections.(Enumerator接口:允許用迭代器模式來遍歷元素

集合;

2)IEnumerator<T>從lEnumerator派生,lEnumerator接口包含3個成員:bool

MoveNextf),從集合中的一個元素移動到下一個元素;只讀屬性

Current,它返回當前元素;Reset()方法拋出一個

NotlmplementedException;

3)集合不直接支持IEnumerator<T>和(Enumerator接口;

4)IEnumerable<T>接口,唯一的方法就是GetEnumerator():返回支持

IEnumerator<T>的一*個對象。

5.推遲執(zhí)行

1)Lambda表達式是可以傳遞到別的地方的委托一一是一個對方法的引用;

聲明時,不執(zhí)行,在調(diào)用時才執(zhí)行。

2)隱式觸發(fā)Lambda表達式的執(zhí)行:foreach循環(huán)內(nèi)會觸發(fā)Lambda表達式的

執(zhí)行;調(diào)用Enumberable的Count。函數(shù),會再次為每一項觸發(fā)Lambda表

達式;調(diào)用ToArray()或者ToList(),ToDictionary,ToLookup(),會為每一項

觸發(fā)Lambda表達式;

3)使用“ToXXX”方法來轉(zhuǎn)換集合,返回的是標準查詢運算符已處理過的一

個集合;此時再遍歷新的結(jié)果集合,則不會再觸發(fā)Lambda表達式

6.查詢表達式Linq

1)輸出的是一個IEnumerable<T>或IQueryable<T>集合;

2)from后面緊著的,是集合中的每一項

3)在select子句中,可以對from子句的表達式所收集到的東西進行投射,獲

得完全不同的一個數(shù)據(jù)類型;

4)也是支持推遲執(zhí)行的。

5)C#編譯器將查詢表達式轉(zhuǎn)換成CLR能理解的方法調(diào)用

6)實現(xiàn)隱式執(zhí)行:編譯器將查詢表達式轉(zhuǎn)換成在目標上調(diào)用的方法,它獲取

委托作為參數(shù),直到以后執(zhí)行時才拿出來使用。

7.集合

1)集合接口:

IList<T>:用于支持通過索引來獲取值;繼承ICollection<T>

IDictionary<TKey,T\/alue>:通過鍵來獲取值;繼承ICollection<T>

IComparable<T>:實現(xiàn)排序,有一個CompareTo()方法

ICollection<T>:包含兩個成員:Count和CopyTo();繼承IEnumerable<T>

2)列表集合類:List<T>

3)字典集合:Dictionary<TKey,TValue>存儲的是一個"名稱/值”對;其中名

稱相當于一個獨一無二的鍵,可以利用它查找對應(yīng)的元素;利用鍵來進行

查找效率非常高(因為鍵存儲在一個散列表中)

4)字典類沒有特定的順序,元素使用散列碼存儲在一個散列表中,這樣可以

實現(xiàn)快速檢索。

5)已排序集合:

SortedDictionary<Tkey,TValue>:按照鍵排序的

SortedList<T>:按照值排序的

6)棧集合:Stack<T>后入先出

Push。方法將元素送人集合,元素不必是唯一的;

Pop()方法按照與添加時相反的順序獲取并刪除元素;

Peek()方法返回Pop()方法將獲取的下一個元素

Contains。方法用于判斷一個元素是否存在于棧的某個地方

7)隊列集合:Queue<T>先入先出

Enqueue。方法:入隊(在隊列的一端將對象放入隊列)

Dequeue。方法:出隊(從另一端移除它們)

8)鏈表:LinkedList<T>:允許正向和反向遍歷

8.索引運算符

1)一對方括號,通常用于索引一個集合;

2)為了定義一個索引運算符,必須將成員命名為this,并在它后面添加一對

方括號來標識參數(shù)

3)索引器([])的CIL屬性名稱默認為Item

9.迭代器

1)描述了如何循環(huán)遍歷(也就是迭代)集合類中的數(shù)據(jù);

2)C#編譯器遇到一個迭代器,會把它的內(nèi)容擴展成實現(xiàn)了枚舉數(shù)模式的CIL

代碼;

3)迭代器類似于函數(shù),但它不是返回(return)值,而是生成值;

4)迭代器用內(nèi)置的狀態(tài)機去跟蹤當前和下一個元素。迭代器每次遇到新的

yieldreturn語句時,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論