本文歡迎轉載,原文地址:http://www.cnblogs.com/DjlNet/p/7192354.htmlhtml
關於這本書(《深刻理解C# 第三版》)的詳細狀況以及好壞,自行搜索便可,我就不囉裏囉嗦的,此文責在備份,意在記錄一下第二次閱讀當中發現原先囫圇吞棗之處,也爲了記憶深入吧。對這裏還有一本《Clr via C# 第四版》也準備二次閱讀,關於精度細讀章節,知乎傳送門( 趙姐夫的回答 ): https://www.zhihu.com/question/27283360。就在昨天(9月9號)北京和上海相繼展開了技術分享會(有同步直播),這裏要給北京的sqlserver演講的老哥點贊,講得不錯挺落地和實在的,還有上海的分享的【.Net 微服務實戰】,看了內心挺有感觸的,並非說從知識或者實踐的層面領悟到有多少有多少,而是理解和明白這玩意兒爲什麼而生,培養一點大局觀和思惟套路吧,畢竟在DDD、微服務大行其道的今天只有不斷學習,而後溫故而知新,可能才能知道它們想表達的含義吧!sql
上面扯了一些口水話,其實在學習偏架構的知識時候,那麼必經之路即是對語言基礎的足夠掌握以及對上層框架的理解掌握,那麼今天再去扯架構和框架以前就來回顧一下關於語言的一些小知識,如下是在下記錄一些書中查漏補缺自我的備份記憶使用,其中可能也包含如下不經常使用或者小知識,大神大佬請自動忽略 ,哈哈。架構
我這裏摘錄引用書中部分描敘:首先「引用傳遞」的正式定義至關複雜,要涉及左值和相似的計算機科學術語,可是最重要的一點是,假如以引用傳遞的方式來傳遞一個變量,那麼調用的方法能夠經過更改其參數值,來改變調用者的變量值(說到這裏有木有想到 ref out 關鍵字,是的它們就能夠達到引用傳遞的效果)。那麼默認狀況,就是沒有顯示使用關鍵詞的狀況,引用類型變量的值纔是引用(相似: 0x12345678 這種),而不是對象自己,且不須要按引用來傳遞參數自己,就能夠更改該參數引用的那個對象的內容。例如:下面的方法更改了相關對象StringBuilder的內容,可是調用者的表達式引用的仍然是以前的那個對象:框架
void AppendHello(StringBuilder builder) { builder.Append("Hello"); }
調用這個方法時,參數值(對StringBuilder的一個引用)是以值傳遞的方式傳遞的。若是想在方法內部更改builder的變量值,如:builder=null;
對調用者來講是看不見的。異步
對於全部的封閉類型,JIT的職責就是將泛型類型的IL轉換爲本地代碼,咱們以List
注意Nullable
int? a=null; if(a==null){ .... }
,與null比較其實在編譯器生成IL代碼中,被轉換爲調用
a.HasValue
,對a賦值爲null,其實也是調用了Nullable
劃重點:
一、捕獲的是變量自己,而不是建立委託實例時它的值
二、捕獲的變量的生存週期被延長了,至少和捕獲它的委託同樣長
三、多個委託能夠捕獲同一個變量
四、在循環內部,同一個變量聲明實際上會引用不一樣的變量「實例」(這點在R#也會提示開發者)
五、若是捕獲的變量不會發生改變,就不須要擔憂
六、在C#5或者以上修正foreach的表達含義,可是for依然須要注意。微服務
這裏直接引用書中的代碼增強記憶和再次熟悉下流程,以下圖所示代碼:
關於代碼的執行流程那得自個兒看看,慢慢跟着執行流程,相信就能明白Yield在代碼執行中起到的做用,就貌似能在不一樣的方法之間跳躍,總的來講能夠歸爲幾點:
一、在第一次調用MoveNext以前,CreateEnumerable中的代碼不會被調用
二、全部工做在調用MoveNext時就完成了,獲取Current的值不會執行任何代碼
三、在yield return的位置,代碼會中止執行,方法暫時返回調用者方法,在下一次執行MoveNext時有繼續在下一行代碼繼續執行
四、在一個方法中的不一樣位置能夠編寫多個yield return語句
五、代碼不會在最後的yield return處結束而是經過返回false的MoveNext調用來結束方法的執行
上面說了這麼多,在看到第3和4點的時候有沒有感受到await的部分做用似曾相識,await也可讓方法返回並且能夠等在那裏等到結果拿到以後接着那個「斷點」繼續執行,並且在一個Async標記的異步方法中能夠,有多個await的拆包操做,因此在必定程度上面yield在思想和設計層面上,給後面的C#5的異步埋下了鋪墊。從狀態機的角度來看(這塊並非很熟悉,因此說錯了,請斧正)在C#5中爲迭代器塊而生成的狀態機和那些異步函數而生成的狀態機之間的類似性是驚人的。異步開發中兩個複雜的問題就是:一、處理狀態 二、在感興趣的事情發生以前進行有效的暫停,迭代器使得這兩個問題得以完美的解決。 這裏提供一下yield實現異步的僞代碼,也是書中的代碼片斷:(僞代碼是基於CCR實現的,主要是明白它想傳遞表達的意思,便可代碼部分看看就好)sqlserver
static IEnumerator<ITask> ComputeTotalStockVal.(str.user,str.pass) { string token=null; yield return Arbiter.Receive(false,AuthService.CcrCheck(user,pass), delegate(string t){ token=t; }); IEnumerable<Holding> stocks=null; IDictionary<string,decimal> rates=null; yield return Arbiter.JoindReceive(false, DbService.CcrGetStockHoldings(token), StockService.CcrGetRate(token), delegate(IEnumerable<Holding> s,IDictionary<string,decimal> r) { stocks=s; rates=r; }); OnRequestComplete(ComputeTotal(stocks,rates)); }
大體對上面代碼作個解釋說明雖然是僞代碼,CCR對咱們的代碼進行了調用也就是調用MoveNext,第一個yield return纔會執行,AuthService裏面的CcrCheck方法啓動一個異步請求,CCR會等待直到它完成,而後提供給它的委託來處理拿到的結果也就是token,而後接着再次調用MoveNext,方法接着執行,JoindReceive並行啓動兩個異步請求,在兩個請求都完成的狀況下,利用後續的委託去處理結果,在這以後MoveNext再次調用,就完成了所有的請求處理了。學習
再回看一些基礎知識的時候,才發覺原來語言層面的設計不比一些高層架構的設計的重要性和觀賞性差(雖然沒什麼可比性,哈哈),好了,天不早了,後面應該會出續篇,等這個完了以後,應該會開始對一些你們關注的點出發,腳踏實地的從代碼、需求和設計層面考慮去寫一些可以使用的代碼片斷或者程序設計,用做之後參考或者借鑑。最最後,好好給本身一記耳光,咋就作人真懶吶,看看離上次發文都多長時間了,送給本身的話:從如今起作一個不那麼懶的人吧!謹記!!!