程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 溫故知新---重讀C#InDepth(二),

溫故知新---重讀C#InDepth(二),

編輯:C#入門知識

溫故知新---重讀C#InDepth(二),


一本好書,或是一本比較有深度的書,就是每次研讀的時候都會有新的發現。

好吧,我承認每次讀的時候都有泛泛而過的嫌疑~~

這幾年一直專注於C#客戶端的開發,逐步從迷迷糊糊,到一知半解,再到自以為是,最後沉下心重新審視。也許這也是一種進步一種自我學習的過程。

前面啰嗦了這麼多,希望大家也能不那麼浮躁的“深入理解”C#這門語言的每個知識點。本文總結書本中的知識,在結合實際應用場合進行概述,如果有不正確的地方,還請不吝指教。

文章中的內容比較淺顯,請高手略過此文。

 

4. 程序閉包

程序閉包的問題是由於程序對某些變量進行了預判和處理(個人理解,若有誤或不足請指正)使得某些變量理應作為值類型卻變為了引用類型導致數據異常。

當然,大多數情況下,我們是不會遇到這樣的問題,但在某些情況下,我們不得不注意並分析問題的根本原因,BUG永遠不是隨機的。

下面通過幾個例子逐步來理解閉包的概念:

例4.1

        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            int outerVariableCaptured = 5; // 外部變量(被捕獲)
            int outerVariableUnCaptured = 50; // 外部變量(未捕獲)

            if (DateTime.Now.Hour <= 24)
            {
                int normalLocalVariable = 1; // 普通方法的局部變量,不是外部變量,因為在其作用域內無匿名方法。
                this.Txb_Msg.Text += string.Format("普通方法的局部變量 = {0}", normalLocalVariable) + System.Environment.NewLine;
            }

            Action x = new Action(() =>
            {
                int anonLocal = 2; // 匿名方法的局部變量
                this.Txb_Msg.Text += string.Format("匿名方法的局部變量 = {0}", anonLocal) + System.Environment.NewLine;
                this.Txb_Msg.Text += string.Format("匿名方法中被捕獲的外部變量 = {0}", outerVariableCaptured)
                    + System.Environment.NewLine; // 匿名方法中調用了作用域外的變量,所以變量變為被捕獲的外部變量
            });

            this.Txb_Msg.Text += string.Format("普通方法的未捕獲的外部變量 = {0}", outerVariableUnCaptured) + System.Environment.NewLine;

            x();
        }
輸出結果:
普通方法的局部變量 = 1
普通方法的未捕獲的外部變量 = 50
匿名方法的局部變量 = 2
匿名方法中被捕獲的外部變量 = 5

4.1中是讓大家了解外部變量,局部變量,捕獲等相關概念。其中最重要的是被捕獲的外部變量。

例4.2

        private void Button3_Click(object sender, RoutedEventArgs e)
        {
            // 證明被捕捉的局部變量聲明周期被延長了。
            OnCreateDelegate += MainWindow_OnCreateDelegate;

            this.Dispatcher.Invoke(OnCreateDelegate(this)); // 此處Invoke容易引起歧義:原因在於Invoke事件之後返回的還是一個事件。
            // Counter是值類型,逃脫其作用域時棧上數據會被回收,真實的情況是這樣嗎?
            // 從另一個側面也說明了,值類型是在棧上還是堆上,依賴於創建對象的類型。
        }
        private Delegate MainWindow_OnCreateDelegate(object sender)
        {
            var frm = sender as MainWindow;
            int Counter = 1;
            var a = new Action(() =>
            {
                frm.Txb_Msg.Text += string.Format("委托內部的變量值 = {0}", Counter) + System.Environment.NewLine;
                Counter++;
            });
            a();

            return a;
        }
輸出:
委托內部的變量值 = 1
委托內部的變量值 = 2

這個例子要說明的是Counter其值類型原本的生存周期應該在MainWindow_OnCreateDelegate(object sender)方法中,可是偏偏卻逃離了方法的作用域,這就是我們所說的值類型是在堆上海事棧上
完全取決於其初始化的位置是在棧上還是在堆上。

 

例4.3

        private void Button4_Click(object sender, RoutedEventArgs e)
        {
            // 更復雜的一些情況
            var methods = new Action[2];
            int outside = 10; // 實例化變量一次
            for (int i = 0; i < 2; i++)
            {
                int inside = 100; // 實例化變量多次
                methods[i] = new Action(() =>
                {
                    this.Txb_Msg.Text += string.Format("Inside Value = {0}; Outside Value = {1} ", inside, outside) + System.Environment.NewLine;
                    inside++;
                    outside++; // 匿名方法捕獲的變量
                });
            }

            methods[0].Invoke();
            methods[0].Invoke();
            methods[0].Invoke();
            methods[1].Invoke();


        }
輸出結果:
            /***************Outside變量內存共享*************
             * Inside Value = 100; Outside Value = 10 
             * Inside Value = 101; Outside Value = 11 
             * Inside Value = 102; Outside Value = 12 
             * Inside Value = 100; Outside Value = 13 
             * *******************************************/

這個例子就得好好想想了,outside和inside的值到底會是什麼?為什麼會這樣?
原因在於inside在For循環的內部初始化了多次,也就是說For循環幾次,就有幾個獨立的inside對象,雖說它是值類型。

 

例4.4

這個例子摘自《編寫高質量代碼:改善C#程序的157個建議》

        private void Button5_Click(object sender, RoutedEventArgs e)
        {
            // 閉包陷阱 
            var methods = new Action[2];
            for (int i = 0; i < 2; i++)
            {
                int inside = i; // 實例化變量多次
                methods[i] = new Action(() =>
                {
                    this.Txb_Msg.Text += string.Format("Inside Value = {0}; Index Value = {1} ", inside, i) + System.Environment.NewLine;
                });
            }
            methods[0].Invoke();
            methods[1].Invoke();

            /*****************閉包陷阱*********************
             * 當使用i的值時,i就是前面說的共享變量(捕獲的外部變量),所以總是輸出i的最大值。
             * 當使用Inside值時,Inside就是內部變量,每次創建對象都重新生成,所以此處inside的值是遞增,即緩存下i的值。
             * 對於IL,其創建了Tempclass.i來代替i,導致了i值共享。
             * *******************************************/ 
        }
輸出結果:
Inside Value = 0; Index Value = 2 
Inside Value = 1; Index Value = 2 

其實如果用ILDasm來看的話,針對i這個對象,IL生成了一個DisplayClass(就是一個名字而已)這樣一個類,最總導致了,i變為引用類型,數據異常。

 

 

持續更新:示例代碼下載


各位幫幫我,問英語中的重讀與非重讀是什回事哦?越仔越好

英語單詞重讀規律淺探(ZT)發音規則主要是針對重讀音節的,因此,如何確定雙音節詞和多音節詞的重讀音節,就成了實現單詞“見即能讀”的關鍵。

雙音節詞和多音節詞中,哪一個音節重讀,往往涉及詞的構造,因此有必要首先介紹一下主要的構詞方法。

英語的構詞方法很多,但主要有三種:(1)綴合法:通過前綴或後綴構成另一個詞。例如:luck(運氣)→lucky(幸運的),unlucky(不幸的)。(2)轉化法:由一個詞類轉化為另一個詞類。例如:water(n.水)→water(v.澆水)。(3)合成法:由兩個或更多個的詞合成為一個詞。例如:book+bag→bookbag(書包);mother+in+law→mother-in-law(岳母,婆婆)。

二、雙音節詞的重讀規律

(一)雙音節詞重讀的一般傾向

1.雙音節動詞傾向於第二個音節重讀。例如:absorb(吸收),behave(舉止),forget(忘記),receive(接收)。

2.動詞以外的雙音節詞,傾向於第一個音節重讀。例如:custom(n.習慣),distant(adj.遙遠的),second(num.第二),many(pron.許多),often(adv.經常),into(prep.進入),after(conj.在……之後)。

名詞、形容詞、副詞的後綴,大都是非重讀的,如:-er,-or,-ess,-ism?-tion?-sion,-ssion?-ment?-ship?-hood?-age?-ure?-dom?-ey?-ance?-our?-ent?-ace?-ow?-ic(s)等名詞後綴;-less?-ish?-ive?-ous?-able?-ible?-ic?-some?-like?-en-ed?-al?-ant,-ful?-ing?-ty?-ly等形容詞後綴。-ly?-ward(s),-wise等副詞後綴。這也進一步加重了這類詞第一個音節重讀的傾向。僅舉幾例說明。名詞:actor(演員),nation(國家);形容詞:useful(有用的),dirty(髒的);副詞:really(真地);數詞:twenty(二十)。

3.某些單詞既可以作動詞,又可以作名詞或形容詞。作動詞時,第二個音節重讀;作名詞或形容詞時,第一個音節重讀。這反映出兩種傾向的明顯對比。例如:-rekord作動詞“記錄”解時讀〔ri′k?:d〕,作名詞“記錄”解時讀〔-rek?d?;present作動詞“贈送”解時讀〔prizent〕,作名詞“禮物”解時讀〔′prez?nt〕;absent作動詞“缺席”解時讀〔?b′sent〕,作形容詞“缺席的”解時讀〔′?bs?nt〕。

(二)影響雙音節詞重讀傾向的構詞因素

上述雙音節動詞傾向於第二個音節重讀,而其他類的雙音節詞傾向於第一個音節重讀,但這並不意味著所有的雙音節詞都是如此。據統計,90%的雙音節動詞都符合第二個音節重讀傾向,而約60%的非動詞雙音節詞符合第一個音節重讀傾向。

雙音節詞的重讀還要受到單詞結構的影響。

1.詞綴的影響

①帶有-en?-er-,-ish,-le,-y,-ow等非重讀後綴的動詞,第二個音節不重讀,第一個音節重讀。例如:happen(發生),open(打開),finish(結束),struggle(奮斗),carry(攜帶),swallow(吞咽),borrow(借來)。

②帶有a-,be-,to-,ex-等前綴的副詞、形容詞、介詞、連詞以及帶有-ee和-self結尾的名詞......余下全文>>
 

溫故知新 歌詞

歌曲名:溫故知新
歌手:農夫
專輯:風生水起

農夫 - 溫故知新
作曲:DJ Galaxy 作詞:C君、6永
農夫 - 溫故知新
ONE TWO THREE齊話聲
456嗌陸WING
今次唔明唔緊要
至緊要下次我聽得清
今次唔齊唔緊要
得你一個嗌都動聽
oh 叫佢食陽光空氣
Lalalalalala lalala
我話愛似系陳冠希(wohoho~)
你愛一架飛機我愛一個杯
你愛我細佬我愛你個妹
你應愛李英愛李英愛愛李英宰
定系愛冇話應該唔應該
456嗌陳冠希
紅唔紅唔緊要
我呢刻好似啰左傑青
愛愛有人話真愛系無價
愛愛我話真愛無得講價
首先要有大把身家
再有奶媽管家
車唔只得一架最好有司機揸
你話咁先至愛我
愛情系現實
你無車無樓無番狗做乜要拖我手
女人最忌無品男人最忌無銀
所以幾百張心意卡比唔上白金嘅附屬卡
林子祥無呃你系你自己呃自己
陳冠希話呢d咁既女有冇搞X錯
但是而家我女友真系一d都唔椤
唔要銀紙唔要Dior
淨系想成日攬住我
有绯聞既事佢唔會信蘋果
佢唔會發火因我時間唔多
愛情阻住用love is all
每次見你你又全情入戲
每次約你你實最快出黎
每次送禮你亦從無厭棄
去到最尾我愛你你不理
有件事要話你地知
尋晚我地去食壽司我咁啱經過女廁
見到有個女士著住白色短裙喱士
佢話我funny我話受即刻交換電話地址
求你觸電啱啱講再見
又再即刻想見
尋晚相聚今晚跟你去
後晚跟他一對
STOP……
大大步走上前大大步
走 屬於你自己嘅路
唔好著人地對鞋 走人地條路
NO! 我谂我揾到
我唔系rap嘅表表啫
我d力都系用左少少啫
我淨系想各位先生小小姐
記得我個名叫咩 yeah 謝謝
呢首歌,送俾鐘意我地音樂既你
咁多位老死,ByeBye~

music.baidu.com/song/1180442
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved