免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
《深入理解 C# (第2版)》 - 學(xué)習(xí)筆記

《深入理解 C#》 (第2版)

========== ========== ==========
[作者] (英) Jon Skeet
[譯者] (中) 周靖 朱永光 姚琪琳
[出版] 人民郵電出版社
[版次] 2012年01月 第1版
[印次] 2012年01月 第1次 印刷
[定價] 79.00元
========== ========== ==========

【關(guān)于本書】

具體地說, C# 作為一種語言,它的基礎(chǔ)是各種各樣的 “框架庫” (.NET Framework 中的各種庫) 以及一個強大的運行時 (runtime) 。借助它們,我們可以將抽象的東西轉(zhuǎn)變成現(xiàn)實。

【第01章】

(P013)

LINQ (Language Integrated Query , 語言集成查詢) ,是 C# 3 的核心之所在。顧名思義。 LINQ 是關(guān)于查詢的,其目的是使用一致的語法和特性,以一種易閱讀、可組合的方式,使對多數(shù)據(jù)源的查詢變得簡單。

(P014)

查詢表達式唯一的好處就是 where 子句顯得更簡單。

【第02章】

(P023)

實際上,委托在某種程度上提供了間接的方法。換言之,不需要直接指定一個行為,而是將這個行為用某種方式 “包含” 在一個對象中。

可以選擇將委托類型看做只定義了一個方法的接口,將委托的實例看做實現(xiàn)了那個接口的一個對象。

(P024)

為了讓委托做某事,必須滿足4個條件 :

1. 聲明委托類型;

2. 必須有一個方法包含了要執(zhí)行的代碼;

3. 必須創(chuàng)建一個委托實例;

4. 必須調(diào)用 (invoke) 委托實例;

(P026)

如果有一個委托類型的變量,就可以把它視為方法本身。

(P028)

委托實例實際有一個操作列表與之關(guān)聯(lián),這稱為委托實例的調(diào)用列表 (invocation list) 。

System.Delegate 類型的靜態(tài)方法 Combine 和 Remove 負責(zé)創(chuàng)建新的委托實例。其中, Combine 負責(zé)將兩個委托實例的調(diào)用列表連接到一起,而 Remove 負責(zé)從一個委托實例中刪除另一個的調(diào)用列表。

委托是不易變的,創(chuàng)建了一個委托實例后,有關(guān)它的一切就不能改變。這樣一來,就可以安全地傳遞委托實例,并把它們與其他委托實例合并,同時不必擔(dān)心一致性、線程安全性或者是否有其他人試圖更改它的操作。

(P029)

事件不是委托類型的字段。

對于事件來說,必須是一個委托類型。

(P030)

對于一個純粹的事件,你所能做的事情就是訂閱 (添加一個事件處理程序) 或者取消訂閱 (刪除一個事件處理程序) 。

類內(nèi)的代碼能看見字段;類外的代碼只能看見事件。

(P037)

數(shù)組類型是引用類型,即使元素類型是值類型。

枚舉是值類型。

委托類型是引用類型。

接口類型是引用類型,但可由值類型實現(xiàn)。

(P039)

變量的值是在它聲明的位置存儲的。

只有局部變量 (方法內(nèi)部聲明的變量) 和方法參數(shù)在棧上。

(P040)

當(dāng)你調(diào)用類型變量值的 GetType() 方法時總是伴隨著裝箱過程,因為它不能被重載。

(P041)

引用類型作為方法參數(shù)使用時,參數(shù)默認是以 “值傳遞” 方式來傳遞的 —— 但值本身是一個引用。

【第03章】

(P047)

所謂 “函數(shù)化” 的編程風(fēng)格,是指鼓勵開發(fā)者更多地利用委托。

(P048)

從根本上說,泛型實現(xiàn)了類型和方法的 “參數(shù)化” ,就像在普通的方法調(diào)用中,經(jīng)常要用參數(shù)來告訴它們使用什么值。

(P052)

類型參數(shù)是真實類型的占位符。

在泛型聲明中,類型參數(shù)要放在一對尖括號內(nèi),并以逗號分隔。

使用泛型類型或方法時,要用真實的類型代替,這些真實的類型稱為類型實參 (type argument) 。

如果沒有為任何類型參數(shù)提供類型實參,聲明的就是一個未綁定泛型類型 (unbound generic type) 。如果指定了類型實參,該類型就稱為一個已構(gòu)造類型 (constructed type) 。

我們知道,類型 (無論是否是泛型) 可以看做是對象的藍圖。同樣,未綁定泛型類型是已構(gòu)造類型的藍圖。

在 C# 代碼中,唯一能看見未綁定泛型類型的地方 (除了作為聲明之外) 就是在 typeof 操作符內(nèi)。

類型參數(shù) “接收” 信息,類型實參 “提供” 信息,這個思路與 方法參數(shù) / 方法實參 是一樣的。只不過類型實參必須為類型,而不能為任意的值。只有在編譯時才能知道類型實參的類型,它可以是 (或包含) 相關(guān)上下文中的類型參數(shù)。

(P054)

泛型類型可以重載,只需改變一下類型參數(shù)的數(shù)量就可以了。

(P057)

將 API 的一部分變成泛型后,以前強類型的方法調(diào)用就需要進行強制類型轉(zhuǎn)換。

(P062)

調(diào)用泛型方法時,指定類型實參常常會顯得很多余。

類型推斷只適用于泛型方法,不適用于泛型類型。

(P063)

在 C# 語言規(guī)范中,只提供了數(shù)量有限的推斷步驟。

雖然很少需要用到默認值,但它偶爾還是有用的。

(P064)

輸出參數(shù)也稱為 out 參數(shù),如果希望由方法本身初始化參數(shù),允許向方法傳遞一個未初始化的實參,那么在聲明參數(shù)時,就要附加 out 關(guān)鍵字作為前綴。

(P066)

共有 4 個主要的泛型接口可用于比較。 IComparer<T> 和 IComparable<T> 用于排序 (判斷某個值是小于、等于還是大于另一個值) ,而 IEqualityComparer<T> 和 IEquatable<T> 通過某種標(biāo)準(zhǔn)來比較兩個項的相等性,或查找某個項的散列 (通過與相等性概念匹配的方式) 。

如果換一種方式來劃分這 4 個接口, IComparer<T> 和 IEqualityComparer<T> 用于那些能夠比較兩個不同值的類型,而 IComparable<T> 和 IEquatable<T> 的實例則用于它們本身和其他值之間的比較。

(P073)

一個基本的原則是,如果沒有問題,泛型接口都應(yīng)該繼承對應(yīng)的非泛型接口,這樣可以實現(xiàn)協(xié)變性。

(P074)

實現(xiàn)接口所規(guī)定的的方法或?qū)傩詴r,附加接口名作為前綴,即稱為 “顯式接口實現(xiàn)” 。

(P075)

反射的一切都是圍繞 “檢查對象及其類型” 展開的。

(P078)

泛型不支持協(xié)變性 —— 它們是不變體。

【第04章】

(P091)

Nullable<T> 最重要的部分就是它的屬性,即 HasValue 和 Value 。

(P092)

Nullable<T> 引入了一個名為 GetValueOrDefault 的新方法,它有兩個重載方法,兩者均在存在一個實例的前提下返回該實例的值,否則返回一個默認值。其中一個重載方法沒有任何參數(shù) (在這種情況下會使用基礎(chǔ)類型的泛型默認值) ,另一個重載方法則允許你指定要返回的默認值。

【第05章】

(P114)

C# 2 支持從方法組到一個兼容委托類型的隱式轉(zhuǎn)換。

(P117)

根據(jù)約定,事件處理方法應(yīng)具有包含兩個參數(shù)的簽名。第 1 個參數(shù)是 object 類型,代表事件的來源;第 2 個參數(shù)則負責(zé)攜帶與事件有關(guān)的任何額外信息,該參數(shù)是從 EventArgs 派生的一個類型。

返回類型協(xié)變性和參數(shù)類型逆變性可以同時使用,雖然這樣做幾乎沒有任何實際的用處。

(P119)

.NET 2.0 引入了一個泛型委托類型 Action<T> ,我們將在例子中使用委托。它的簽名非常簡單 (除了它是泛型這一事實以外) : public delegate void Action<T>(T obj) 。

(P120)

匿名方法的語法 : 先是 delegate 關(guān)鍵字,再是參數(shù) (如果有的話) ,隨后是一個代碼塊,其中包含了對委托實例的操作進行定義的代碼。

基本上,在普通方法主體中能做的事情,在匿名方法中都能做。同樣,匿名方法的結(jié)果是一個委托實例,可以像使用其他委托實例那樣使用它。

逆變性不適用于匿名方法,必須指定和委托類型完全匹配的參數(shù)類型。

(P121)

Action<T> 委托的返回類型是 void ,所以不必從匿名方法返回任何東西。

.NET 2.0 中的 Predicate<T> 委托類型,下面列出了它的簽名 : public delegate bool Predicate<T>(T obj) 。

(P122)

謂語通常在需要篩選和匹配操作中使用。

Predicate<T> 類型聲明的返回類型恰好是 bool 。

(P124)

匿名方法是 C# 2 以被捕捉的變量的形式來實現(xiàn),在別的地方成為閉包的一個特性。

(P125)

匿名方法能使用在聲明該匿名方法的方法內(nèi)部定義的局部變量。

(P127)

簡單地說,捕獲變量能簡化編程,避免專門創(chuàng)建一些類來存儲一個委托需要處理的信息 (作為參數(shù)傳遞的信息除外) 。

FindAll 的參數(shù)是一個 Predicate<T> 委托。

【第06章】

(P138)

如果方法聲明的返回類型是非泛型接口,那么迭代器塊的生成類型 (yield type) 是 object ,否則就是泛型接口的類型參數(shù)。

在迭代器中不允許包含普通的 return 語句 —— 只能是 yield return 。

(P141)

迭代器代碼塊不能實現(xiàn)具有 ref 或 out 參數(shù)的方法。

(P143)

只要調(diào)用者使用了 foreach 循環(huán),迭代器塊中的 finally 將按照你期望的方式工作。

(P147)

迭代器方法中的 using 語句扮演了 try / finally 塊的角色。

(P148)

LINQ 的核心特性之一,是使用 Where 方法進行篩選。

【第07章】

(P154)

創(chuàng)建分部類型是非常容易做的事情 —— 你只需在涉及的每個文件的類型的聲明部分附加一個上下文關(guān)鍵字 partial 。

(P158)

分部方法的聲明方式與抽象方法相同 : 只使用 partial 修飾符提供簽名而無須任何實現(xiàn)。同樣,實際的實現(xiàn)還需要 partial 修飾符,不然就和普通方法一樣了。

由于方法可能不存在,分部方法必須具有 void 返回類型,不能獲取 out 參數(shù)。它們必須是私有的,不過可以是靜態(tài)的 并且 / 或是 泛型的。如果方法沒有在任何文件中實現(xiàn),那么整個調(diào)用語句就會被移除,包括任何參數(shù)的計算語句。

(P159)

實際上如果不存在可見的構(gòu)造函數(shù) (包括受保護的) ,那么類實際上也就是密封的了。

(P160)

如果你不為類提供任何構(gòu)造函數(shù),那么 C# 1 編譯器總是會提供一個公有的默認的無參數(shù)構(gòu)造函數(shù)。

我們不希望出現(xiàn)任何可見的構(gòu)造函數(shù),所以不得不提供一個私有的。

C# 2 編譯器知道靜態(tài)類不用包含任何構(gòu)造函數(shù),所以它也不會提供默認的。實際上,編譯器在類定義上執(zhí)行了大量的約束 :

1. 類不能聲明為 abstract 或 sealed ,雖然兩者都是隱含聲明的;

2. 類不能設(shè)定任何要實現(xiàn)的接口;

3. 類不能設(shè)定基類型;

4. 類不能包含任何非靜態(tài)成員,包括構(gòu)造函數(shù);

5. 類不能包含任何操作符;

6. 類不能包含任何 protected 或 protected internal 成員;

應(yīng)當(dāng)注意,即使所有成員都必須為靜態(tài)的,你還是要把它們都顯式地聲明為靜態(tài)的,除了嵌套類型和常量。雖然嵌套類型是外圍類的隱式靜態(tài)成員,不過如果不要求的話,嵌套類型本身可以不用是靜態(tài)的。

(P161)

讓類成為靜態(tài)的,就是在說你絕對不會創(chuàng)建該類的任何實例。

在 C# 1 中取值方法和賦值方法必須具有相同的可訪問性 —— 它作為屬性聲明的一部分進行聲明,而不是作為取值方法或賦值方法聲明的一部分進行聲明的。

(P162)

在 C# 的其他地方,在給定的情況下,默認的訪問修飾符可能大部分都是私有的。換句話說。如果某些內(nèi)容能被聲明為私有,那么省略的訪問修飾符就被完全默認為私有。這是一種很好的語言設(shè)計元素,因為這樣很難意外地發(fā)生錯誤 : 如果你希望某些內(nèi)容更加公開,在你使用它的時候會注意到。

如果你不設(shè)定任何東西,那么默認情況下 取值方法 / 賦值方法 和屬性本身整體上保持一致的訪問修飾符。

還要注意,你不能把屬性本身聲明為私有,而讓取值方法是公有的 —— 你只能設(shè)置比屬性更私有的特殊 取值方法 / 賦值方法 。

C# 1 的 using 指令能夠用于兩種情況 —— 一種是為命名空間和類型創(chuàng)建一個別名,另外一種就是將一個命名空間引入到當(dāng)編譯器查找某個類型時可以搜索到的上下文列表中。

在 C# 2 中,有 3 種別名種類 : C# 1 的命名空間別名、全局命名空間別名和外部別名。

(P166)

對 pragma 指令進行描述通常都非常簡單 : pragma 指令就是一個由 #pragma 開頭的代碼行所表示的預(yù)處理指令,它后面能包含任何文本。

【第08章】

(P178)

不能在所有情況下為所有變量都使用隱式類型。只有在以下情況下才能用它 :

1. 被聲明的變量是一個局部變量,而不是靜態(tài)字段和實例字段;

2. 變量在聲明的同時被初始化;

3. 初始化表達式不是一個方法組,也不是一個匿名函數(shù) (不進行強制類型轉(zhuǎn)換) ;

4. 初始化表達式不是 null ;

5. 語句中只聲明了一個變量;

6. 你希望變量擁有的類型是初始化表達式的編譯時類型;

7. 初始化表達式不包含正在聲明的變量;

(P184)

集合初始化列表并非只能應(yīng)用于列表。任何實現(xiàn)了 IEnumerable 的類型,只要它為初始化列表中出現(xiàn)的每個元素都提供了一個恰當(dāng)?shù)墓械?Add 方法,就可以使用這個特性。

(P192)

如果你要創(chuàng)建的一個類型只在一個方法中使用,而且其中只包含了字段和普通屬性,就考慮一下能否使用匿名類型。

(P193)

匿名類型允許你只保留特定情況下需要的數(shù)據(jù),這些數(shù)據(jù)采取的是適用于那種情況的形式,不必每次都單調(diào)重復(fù)地寫一個新的類型。

隱式類型的數(shù)組和匿名類型只有在與其他 C# 3 特性配合的時候才會體現(xiàn)它們的價值。

【第09章】

(P194)

LINQ 的基本功能就是創(chuàng)建操作管道,以及這些操作需要的任何狀態(tài)。這些操作表示了各種關(guān)于數(shù)據(jù)的邏輯 : 如何篩選、如何排序以及如何將不同的數(shù)據(jù)源聯(lián)接到一起,等等。當(dāng) LINQ 查詢在 “進程內(nèi)” 執(zhí)行時,那些操作通常用委托來表示。

LINQ to Objects 處理的是同一個進程中的數(shù)據(jù)序列。相比之下,像 LINQ to SQL 這樣的 provider 將工作交給 “進程外” 的系統(tǒng) (比如數(shù)據(jù)庫) 去處理。

(P195)

執(zhí)行委托只是 LINQ 的眾多能力之一。

從許多方面, Lambda 表達式都可以看做是 C# 2 的匿名方法的一種演變。

匿名方法能做的幾乎一切事情都可以用 Lambda 表達式來完成。

匿名方法可以簡明地忽略參數(shù),但 Lambda 表達式不具備的這一特性。

在 .NET 3.5 的 System 命名空間中,有 5 個泛型 Func 委托類型。 Func 并無特別之處 —— 只是它提供了一些好用的預(yù)定義泛型類型,在很多情況下能幫助我們處理問題。每個委托簽名都獲取 0 ~ 4 個參數(shù),參數(shù)類型是用類型參數(shù)來指定的。最后一個類型參數(shù)用作每種情況下的返回類型。

(P196)

當(dāng)你想使用 void 為返回類型時,可使用 Action<...> 系列的委托,其功能相同。

Action 的單參數(shù)的版本在 .NET 2.0 中就有了,但其他都是 .NET 3.5 新增的。

如果 4 個參數(shù)還嫌不夠, .NET 4 將 Action<...> 和 Func<...> 家族擴展為擁有 16 個參數(shù),因此 Func<T1, ..., T16, TResult> 擁有讓人欲哭無淚的 17 個類型參數(shù)。

Lambda 表達式最冗長的形式是 : { 顯式類型參數(shù)列表} => { 語句 } 。

=> 部分是 C# 3 新增的,它告訴編譯器我們正使用一個 Lambda 表達式。

(P197)

在閱讀 Lambda 表達式時,可以將 => 部分看成 “goes to” 。

匿名方法中控制返回語句的規(guī)則同樣適用于 Lambda 表達式 : 如果返回類型是 void ,就不能從 Lambda 表達式返回一個值;如果有一個非 void 的返回類型,那么每個代碼路徑都必須返回一個兼容的值。

對于沒有返回類型的委托,如果只有一條語句,也可以使用這種語法,基本上省略分號和大括號。

表達式,不使用大括號,不使用 return 語句,也不添加分號 : { 顯式類型的參數(shù)列表 } => 表達式 。

編譯器大多數(shù)時候都能猜出參數(shù)類型,不需要你顯式聲明它們。在這種情況下,可以將 Lambda 表達式寫成 : ( 隱式類型的參數(shù)列表 ) => 表達式 。

隱式類型的參數(shù)列表就是一個以逗號分隔的名稱列表,沒有類型。但隱式和顯式類型的參數(shù)不能混合和匹配 —— 要么整個列表都是顯式類型的,要么全部都是隱式類型的。除此之外,如果有任何 out 或 ref 參數(shù),就只能使用顯式類型。

(P198)

如果 Lambda 表達式只需一個參數(shù),而且那個參數(shù)可以隱式指定類型, C# 3 就允許省略圓括號。這種格式的 Lambda 表達式是 : 參數(shù)名 => 表達式 。

是否為 Lambda 表達式的主體使用較短的形式 (指定一個表達式來取代一個完整的代碼塊) ,以及是使用顯式還是隱式參數(shù),這兩個決定是完全獨立的。

(P202)

.NET 3.5 的表達式樹提供了一種抽象的方式將一些代碼表示成一個對象樹。

C# 3 對于將 Lambda 表達式轉(zhuǎn)換成表達式樹提供了內(nèi)建的支持。

(P205)

Lambda 表達式能顯式或隱式地轉(zhuǎn)換成恰當(dāng)?shù)奈袑嵗?/strong>

并非所有 Lambda 表達式都能轉(zhuǎn)換成表達式樹。不能將帶有一個語句塊 (即使只有一個 return 語句) 的 Lambda 轉(zhuǎn)換成一個表達式樹 —— 只有對單個表達式進行求值的 Lambda 才可以。

(P208)

沒有 Lambda 表達式,表達式樹幾乎沒有任何價值。

從一定程度上說,反過來說也是成立的 : 沒有表達式樹, Lambda 表達式肯定就沒那么有用了。

(P218)

匿名函數(shù)是匿名方法和 Lambda 表達式的統(tǒng)稱。

(P219)

Lambda 表達式要想被編譯器理解,所有參數(shù)的類型必須為已知。

在 C# 3 中, Lambda 表達式幾乎完全取代了匿名方法。當(dāng)然,為了保持向后兼容,匿名方法仍是支持的。

【第10章】

(P220)

C# 3 引入了擴展方法的概念,它既有靜態(tài)方法的優(yōu)點,又使調(diào)用它們的代碼的可讀性得到了增強。使用擴展方法,可以像調(diào)用完全不同的類的實例方法那樣調(diào)用靜態(tài)方法。

(P223)

并不是任何方法都能作為擴展方法使用 —— 它必須具有以下特征 :

1. 它必須在一個非嵌套的、非泛型的靜態(tài)類中 (所以必須是一個靜態(tài)方法) ;

2. 它至少要有一個參數(shù);

3. 第一個參數(shù)必須附加 this 關(guān)鍵字作為前綴;

4. 第一個參數(shù)不能有其他任何修飾符 (比如 out 或 ref) ;

5. 第一個參數(shù)的類型不能是指針類型;

(P226)

實例方法肯定會先于擴展方法使用。

在 C# 中,在空引用上調(diào)用實例方法是不允許的。

可以在空引用上調(diào)用擴展方法。

(P227)

在框架中,擴展方法最大的用途就是在 LINQ 中使用。

(P229)

Where 擴展方法是對集合進行篩選的一種簡單但又十分強大的方式 : 它接受一個謂詞,后者應(yīng)用于原始集合中的每個元素。 Where 同樣返回一個 IEnumerable<T> ,但這一次所有與謂詞匹配的元素都被包括到結(jié)果集合中。

(P230)

“返回相同的引用” 模式用于易變類型,而 “返回新實例 (該實例為原始實例更改后的副本)” 模式則用于不易變類型。

(P233)

LINQ 操作符是無副作用的 : 它們不會影響輸入,也不會改變環(huán)境。

(P236)

C# 3 只支持擴展方法而不支持擴展屬性,這稍微限制了流暢接口。

(P239)

我們學(xué)東西不應(yīng)過于急功近利 —— 每次都是為了解決當(dāng)前的一個實際問題才去學(xué)習(xí)。

在軟件工程領(lǐng)域,新的模式和實踐準(zhǔn)則層出不窮,來自一些系統(tǒng)的設(shè)計思想經(jīng)常會 “流竄” 到另一些系統(tǒng)中。這其實是讓軟件開發(fā)始終保持新鮮感的原因之一。

【第11章】

(P241)

序列是 LINQ 的基礎(chǔ)。

(P251)

Cast 通過把每個元素都轉(zhuǎn)換為目標(biāo)類型 (遇到不是正確類型的任何元素的時候,就會出錯) 來處理,而 OfType 首先進行一個測試,以跳過任何具有錯誤類型的元素。

(P254)

編譯器會故意生成一個對 Select 方法的調(diào)用,即使它什么都沒有做。

查詢表達式的結(jié)果和源數(shù)據(jù)從來就不是同一個對象,除非 LINQ 提供器的代碼有問題。從數(shù)據(jù)集成的角度看,這是很重要的 —— 提供器能返回一個易變的結(jié)果對象,并知道即使面對一個退化查詢,對返回數(shù)據(jù)集的改變也不會影響到 “主” 數(shù)據(jù)。

(P255)

OrderBy 和 ThenBy 不同之處非常簡單 : OrderBy 假設(shè)它對排序規(guī)則起決定作用,而 ThenBy 可理解為對之前的一個或多個排序規(guī)則起輔助作用。

(P256)

盡管你能使用多個 orderby 子句,但每個都會以它自己的 OrderBy 或 OrderByDescending 子句作為開始,這意味著最后一個才會真正 “獲勝” 。

let 子句只不過引入了一個新的范圍變量,它的值是基于其他范圍變量。語法是極其簡單的 : let 標(biāo)識符 = 表達式 。

(P258)

let 子句使用對 Select 的另一個調(diào)用,為結(jié)果序列創(chuàng)建匿名方法,并最終創(chuàng)建了一個新的范圍變量 (它的名稱在源代碼中從未看到或用到) 來實現(xiàn)目標(biāo)。

(P260)

如果你打算把一個巨大的序列聯(lián)接到一個極小的序列上,應(yīng)盡可能把小序列作為右邊序列。

(P261)

通常,你希望過濾序列,而在聯(lián)接前進行過濾比在聯(lián)接后過濾要有效得多。

內(nèi)聯(lián)接可用在 SQL 的所有地方,它們實際上是從某個實體導(dǎo)航到相關(guān)聯(lián)的實體上的一種方式,通常是把某個表的外鍵和另外一個表的主鍵進行聯(lián)接。

(P264)

交叉聯(lián)接不在序列之間執(zhí)行任何匹配操作 : 結(jié)果包含了每個可能的元素對。

(P268)

分組表達式通過分組鍵決定了序列如何分組。整個結(jié)果就是一個序列,序列中的每個元素本身就是投影后元素的序列,還具有一個 Key 屬性,這就是那個用于分組的鍵;這樣的組合是封裝在 IGrouping<TKey, TElement> 接口中的,它擴展了 IEnumerable<TElement> 。

(P270)

查詢延續(xù)提供一種方式,把一個查詢表達式的結(jié)果用作另外一個查詢表達式的初始序列。它可以應(yīng)用于 group...by 和 select 子句上,語法對于兩者是一樣的 —— 你只需使用上下文關(guān)鍵字 into ,并為新的范圍變量提供一個名稱就可以了。范圍變量接著能用在查詢表達式的下一部分。

【第12章】

(P277)

LINQ to SQL 需要有關(guān)數(shù)據(jù)庫的元數(shù)據(jù),來知道哪個類與哪個數(shù)據(jù)庫表相對應(yīng)等信息。可以用幾種不同的方式來表示這種元數(shù)據(jù),而我這里使用的是 Visual Studio 內(nèi)嵌的 LINQ to SQL 設(shè)計器。

【第13章】

(P312)

參數(shù) (也稱為形式參數(shù)) 變量是方法或索引器聲明的一部分,而實參是調(diào)用方法或索引器時使用的表達式。

(P313)

如果某個操作需要多個值,而有些值在每次調(diào)用的時候又往往是相同的,這時通??梢允褂每蛇x參數(shù)。

(P314)

指定了默認值的參數(shù)為可選參數(shù)。

(P315)

可選參數(shù)包含一些規(guī)則。所有可選參數(shù)必須出現(xiàn)在必備參數(shù)之后,參數(shù)數(shù)組 (用 params 修飾符聲明) 除外,但它們必須出現(xiàn)在參數(shù)列表的最后,在它們之前為可選參數(shù)。參數(shù)數(shù)組不能聲明為可選的,如果調(diào)用者沒有指定值,將使用空數(shù)組代替??蛇x參數(shù)不能使用 ref 或 out 修飾符。

(P316)

基本上,你必須使用永遠不會改變的真正常量作為可選參數(shù)的默認值。

(P318)

如果要對包含 ref 或 out 的參數(shù)指定名稱,需要將 ref 或 out 修飾符放在名稱之后,實參之前。

(P319)

實參是按照參數(shù)的名稱來匹配的,而不再是參數(shù)的位置。

未命名的實參稱為位置實參。

所有命名實參都必須位于位置實參之后,兩者之間的位置不能改變。位置實參總是指向方法聲明中相應(yīng)的參數(shù) —— 你不能跳過參數(shù)之后,再通過命名相應(yīng)位置的實參來指定。

(P331)

可變性有兩種類型 : 協(xié)變性和逆變性。

協(xié)變性用于向調(diào)用者返回某項操作的值。

逆變性則相反。它指的是調(diào)用者向 API 傳入的值,即 API 是在消費值,而不是產(chǎn)生值。

(P332)

在泛型接口或委托聲明中, C# 4 能夠使用 out 修飾符來指定類型參數(shù)的協(xié)變性,使用 in 修飾符來指定逆變性。

任何使用了協(xié)變和逆變的轉(zhuǎn)換都是引用轉(zhuǎn)換,這意味著轉(zhuǎn)換之后將返回相同的引用。它不會創(chuàng)建新的對象,只是認為現(xiàn)有引用與目標(biāo)類型匹配。

如果類型參數(shù)只用于輸出,就使用 out ,如果只用于輸入,就用 in 。

(P337)

只有接口和委托可以擁有可變的類型參數(shù)。即使類中包含只用于輸入 (或只用于輸出) 的類型參數(shù),仍然不能為它們指定 in 或 out 修飾符。

【第14章】

(P345)

事實上, dynamic 并不代表一個特定的 CLR 類型,它實際上只是包含 System.Dynamic.DynamicAttribute  特性的 System.Object 。

(P347)

dynamic 可用來聲明類型的字段、參數(shù)和返回值。這與 var 形成了鮮明的對比,后者只能用于局部變量。

(P355)

如果兩個方法的簽名包含的參數(shù)類型相同,編譯器將選擇非泛型重載,而不是泛型重載。

(P362)

dynamic 類型的參數(shù)將被視為 object 類型 —— 如果查看編譯后的代碼,將發(fā)現(xiàn)它確實為 object 類型的參數(shù),只不過應(yīng)用了額外的特性。這還意味著在你聲明的方法中,它們的簽名不能只以 dynamic / object 參數(shù)類型來進行區(qū)分。

(P369)

你不能聲明一個基類為 dynamic 的類型,你同樣不能將 dynamic 用于類型參數(shù)的約束,或作為類型所實現(xiàn)的接口的一部分。你可以將其用于基類的類型實參,或在聲明變量時將其用于接口。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服