• <label id="pxtpz"><meter id="pxtpz"></meter></label>
      1. <span id="pxtpz"><optgroup id="pxtpz"></optgroup></span>

        當(dāng)前位置:雨林木風(fēng)下載站 > 技術(shù)開發(fā)教程 > 詳細(xì)頁面

        .NET Delegates: A C# Bedtime Story中文版(上篇)轉(zhuǎn)

        .NET Delegates: A C# Bedtime Story中文版(上篇)轉(zhuǎn)

        更新時間:2022-05-13 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

        作者:Chris Sells
        譯者:榮耀
        【譯注:C#進(jìn)階文章。Chris Sells是《ATL Internals》一書作者之一。譯文中所有程
        序調(diào)試環(huán)境均為Microsoft Visual Studio.NET 7.0 Beta2和 Microsoft .NET Framewo
        rk SDK Beta2。代碼就是文章,請仔細(xì)閱讀代碼J】
        類型耦合
        從前,在南方的一個異國他鄉(xiāng),有一個叫peter的勤勞的工人。他對boss百依百順,但他
        的boss卻是個卑鄙無信的小人,他堅持要求peter不斷匯報工作情況。由于peter不希望
        被boss盯著干活,于是他向boss承諾隨時匯報工作進(jìn)度。peter利用類型引用定期回調(diào)b
        oss來實現(xiàn)這個承諾:
        using System;//【譯注:譯者補(bǔ)充】
        class Worker
        {
         public void Advise(Boss boss)
        {
        _boss = boss;
        }
         public void DoWork()
         {
        Console.WriteLine("Worker: work started");
        if( _boss != null ) _boss.WorkStarted();
        Console.WriteLine("Worker: work progressing");
        if( _boss != null ) _boss.WorkProgressing();
        Console.WriteLine("Worker: work completed");
        if( _boss != null )
         {
        int grade = _boss.WorkCompleted();
        Console.WriteLine("Worker grade = " + grade);
         }
         }
         private Boss _boss;
        }
        class Boss
        {
         public void WorkStarted() { /*boss不關(guān)心. */ }
         public void WorkProgressing() { /*boss不關(guān)心. */ }
         public int WorkCompleted()
         {
        Console.WriteLine("It's about time!");
         return 2; /* out of 10 */
         }
        }
        class Universe
        {
         static void Main()
         {
         Worker peter = new Worker();
         Boss boss = new Boss();
        peter.Advise(boss);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
         }
        }
        /*【譯注:以下是上段程序輸出結(jié)果:
        Worker: work started
        Worker: work progressing
        Worker: work completed
        It's about time!
        Worker grade = 2
        Main: worker completed work
        】*/
        接口
         現(xiàn)在,peter成了一個特殊人物,他不但能夠忍受卑鄙的boss,和universe也建立
        了緊密的聯(lián)系。peter感到universe對他的工作進(jìn)程同樣感興趣。不幸的是,除了保證b
        oss能夠被通知外,如果不為universe添加一個特殊的通知方法和回調(diào),peter無法向un
        iverse通知其工作進(jìn)程。Peter希望能從那些通知方法的實現(xiàn)中分離出潛在的通知約定,
        為此,他決定將方法剝離到接口中:
        using System; //【譯注:譯者補(bǔ)充】
        interface IWorkerEvents //【譯注:這就是分離出來的接口】
        {
         void WorkStarted();
         void WorkProgressing();
         int WorkCompleted();
        }
        class Worker
        {
         public void Advise(IWorkerEvents events) //【譯注:現(xiàn)在傳遞的參數(shù)類型為
        接口引用】
        {
        _events = events;
        }
         public void DoWork()
         {
        Console.WriteLine("Worker: work started");
        if( _events != null ) _events.WorkStarted();
        Console.WriteLine("Worker: work progressing");
        if(_events != null ) _events.WorkProgressing();
        Console.WriteLine("Worker: work completed");
        if(_events != null )
         {
        int grade = _events.WorkCompleted();
        Console.WriteLine("Worker grade = " + grade);
         }
         }
         private IWorkerEvents _events;
        }
        class Boss : IWorkerEvents //【譯注:Boss實現(xiàn)該接口】
        {
         public void WorkStarted(){ /*boss不關(guān)心. */ }
         public void WorkProgressing(){ /*boss不關(guān)心. */ }
         public int WorkCompleted()
         {
        Console.WriteLine("It's about time!");
         return 3; /* out of 10 */
         }
        }
        class Universe
        {
         static void Main()
         {
         Worker peter = new Worker();
         Boss boss = new Boss();
        peter.Advise(boss); //【譯注:或peter.Advise((IWorkerEvents)boss);

        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
         }
        }
        /*【譯注:以下是上段程序輸出結(jié)果:
        Worker: work started
        Worker: work progressing
        Worker: work completed
        It's about time!
        Worker grade = 3
        Main: worker completed work
        】*/
        委托
         不幸的是,由于peter忙于通知boss實現(xiàn)這個接口,以至于沒有顧得上通知univer
        se也實現(xiàn)該接口,但他知道不久就需如此,至少,他已經(jīng)抽象了對boss的引用,因此,
        別的實現(xiàn)了IworkerEvents接口的什么人都可以收到工作進(jìn)度通知。【譯注:請參見上一
        節(jié)代碼示例及譯注】
         然而,peter的boss依然極度不滿,“Peter!”boss咆哮者,“你為什么要通知我
        什么時候開始工作、什么時候正在進(jìn)行工作?我不關(guān)心這些事件,你不但強(qiáng)迫我實現(xiàn)這
        些方法,你還浪費了你的寶貴的工作時間等我從事件中返回。當(dāng)我實現(xiàn)的方法需占用很
        長時間時,你等我的時間也要大大延長!你難道不能想想別的辦法不要老是來煩我嗎?

         此時,peter意識到盡管在很多情況下接口很有用,但在處理事件時,接口的粒度
        還不夠精細(xì)。他還要能做到僅僅通知監(jiān)聽者真正感興趣的事件。因此,peter決定把接口
        里的方法肢解成若干個獨立的委托函數(shù),每一個都好象是只有一個方法的小接口。
        using System; //【譯注:譯者補(bǔ)充】
        delegate void WorkStarted();
        delegate void WorkProgressing();
        delegate int WorkCompleted();
        class Worker
        {
         public void DoWork()
         {
        Console.WriteLine("Worker: work started");
        if( started != null ) started();
        Console.WriteLine("Worker: work progressing");
        if( progressing != null ) progressing();
        Console.WriteLine("Worker: work completed");
        if( completed != null )
         {
        int grade = completed();
        Console.WriteLine("Worker grade = " + grade);
         }
         }
         public WorkStarted started; //【譯注:這樣寫更規(guī)矩:public WorkStarted
        started = null;】
         public WorkProgressing progressing; //【譯注:這樣寫更規(guī)矩:public Work
        Progressing progressing = null;】
         public WorkCompleted completed; //【譯注:這樣寫更規(guī)矩:public WorkComp
        leted completed = null;】
        }
        class Boss
        {
         public int WorkCompleted()
         {
        Console.WriteLine("Better...");
         return 4; /* out of 10 */
         }
        }
        class Universe
        {
         static void Main()
         {
         Workerpeter = new Worker();
         Boss boss = new Boss();
        peter.completed = new WorkCompleted(boss.WorkCompleted);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
         }
        }
        /*【譯注:以下是上段程序輸出結(jié)果:
        Worker: work started
        Worker: work progressing
        Worker: work completed
        Better...
        Worker grade = 4
        Main: worker completed work

        */
        【譯注:對“但在處理事件時,接口的粒度還不夠精細(xì)”的理解可用下例說明,請仔細(xì)
        觀察一下程序,思考一下這樣做的不利之處J
        using System;
        interface IWorkStartedEvent
        {
         void WorkStarted();
        }
        interface IWorkProgressingEvent
        {
         void WorkProgressing();
        }
        interface IWorkCompletedEvent
        {
         int WorkCompleted();
        }
        class Worker
        {
        public void Advise(IWorkCompletedEvent AEvent)
        {
        _event = AEvent;
        }
        public void DoWork()
        {
        Console.WriteLine("Worker: work completed");
        if(_event != null )
         {
        int grade = _event.WorkCompleted();
        Console.WriteLine("Worker grade = " + grade);
        }
        }
        private IWorkCompletedEvent _event;
        }
        class Boss : IWorkCompletedEvent
        {
        public int WorkCompleted()
        {
        Console.WriteLine("Better...");
        return 4; /* out of 10 */
        }
        }
        class Universe
        {
        static void Main()
         {
         Worker peter = new Worker();
         Boss boss = new Boss();
        peter.Advise(boss);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
         }
        }
        /*以下是上段程序輸出結(jié)果:
        Worker: work completed
        Better...
        Worker grade = 4
        Main: worker completed work
        */

        靜態(tài)監(jiān)聽者
         這就達(dá)到了不用boss不關(guān)心的事件去煩他的目標(biāo)。但是,peter還是不能夠使univ
        erse成為其監(jiān)聽者。因為universe是一個全封閉的實體,所以將委托掛鉤在universe的
        實例上不妥的(設(shè)想一下Universe的多個實例需要多少資源...)。peter意識到應(yīng)將委
        托掛鉤于universe的靜態(tài)成員上,因為委托也完全適應(yīng)于靜態(tài)成員:
        using System;
        delegate void WorkStarted();
        delegate void WorkProgressing();
        delegate int WorkCompleted();
        class Worker
        {
         public void DoWork()
         {
        Console.WriteLine("Worker: work started");
        if( started != null ) started();
        Console.WriteLine("Worker: work progressing");
        if( progressing != null ) progressing();
        Console.WriteLine("Worker: work completed");
        if( completed != null )
         {
        int grade = completed();
        Console.WriteLine("Worker grade= " + grade);
         }
         }
         public WorkStarted started = null;
         public WorkProgressing progressing = null;
         public WorkCompleted completed = null;
        }
        class Boss
        {
         public int WorkCompleted()
         {
        Console.WriteLine("Better...");
         return 4; /* out of 10 */
         }
        }
        //【譯注:以上代碼為譯者補(bǔ)充】
        class Universe
        {
        static void WorkerStartedWork()
        {
        Console.WriteLine("Universe notices worker starting work");
        }
        static int WorkerCompletedWork()
        {
        Console.WriteLine("Universe pleased with worker's work");
        return 7;
        }
        static void Main()
        {
        Worker peter = new Worker();
        Boss boss = new Boss();
        peter.completed = new WorkCompleted(boss.WorkCompleted); //【譯注:×

        peter.started = new WorkStarted(Universe.WorkerStartedWork);
        peter.completed = new WorkCompleted(Universe.WorkerCompletedWork);//
        【譯注:這一行代碼使得“×”那一行代碼白做了L】
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
        }
        }
        /*【譯注:以下是上段程序輸出結(jié)果:
        Worker: work started
        Universe notices worker starting work
        Worker: work progressing
        Worker: work completed
        Universe pleased with worker's work
        Worker grade = 7
        Main: worker completed work
        】*/
        事件
         不幸的是,universe現(xiàn)在變得太忙并且不習(xí)慣于注意某一個人—universe用自己的
        委托取代了peter的boss的委托,這顯然是將Worker類的委托字段設(shè)為public的意外的副
        作用。【譯注:請參見上節(jié)例子代碼及譯注】同樣地,如果peter的boss不耐煩了,他自
        己就可以觸發(fā)peter的委托(peter的boss可是有暴力傾向的)
        // peter的boss自己動手了
        if( peter.completed != null ) peter.completed();
        peter希望確保不會發(fā)生這兩種情況。他意識到必須為每一個委托加入注冊和反注冊函數(shù)
        ,這樣監(jiān)聽者就可以添加或移去它們,但誰都不能夠清空整個事件列表。peter自己沒去
        實現(xiàn)這些方法,相反,他使用event關(guān)鍵字讓C#編譯器幫他達(dá)到這個目的:
        class Worker
        {
        //...
        public event WorkStarted started;
        public event WorkProgressing progressing;
        public event WorkCompleted completed;
        }
         peter懂得關(guān)鍵字event使得委托具有這樣的特性:只允許C#客戶用+=或-=操作符添
        加或移去它們自己,這樣就迫使boss和universe舉止文雅一些:
        static void Main()
        {
        Worker peter = new Worker();
         Boss boss = new Boss();
         peter.completed += new WorkCompleted(boss.WorkCompleted);
         peter.started += new WorkStarted(Universe.WorkerStartedWork);
         peter.completed += new WorkCompleted(Universe.WorkerCompletedWork);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
        }
        【譯注:以下是完整代碼:
        using System;
        delegate void WorkStarted();
        delegate void WorkProgressing();
        delegate int WorkCompleted();
        class Worker
        {
         public void DoWork()
         {
        Console.WriteLine("Worker: work started");
        if( started != null ) started();
        Console.WriteLine("Worker: work progressing");
        if( progressing != null ) progressing();
        Console.WriteLine("Worker: work completed");
        if( completed != null )
         {
        int grade = completed();
        Console.WriteLine("Worker grade = " + grade);
         }
         }
        public event WorkStarted started ;
        public event WorkProgressing progressing;
        public event WorkCompleted completed;
        }
        class Boss
        {
         public int WorkCompleted()
         {
        Console.WriteLine("Better...");
         return 4; /* out of 10 */
         }
        }
        class Universe
        {
         static void WorkerStartedWork()
         {
        Console.WriteLine("Universe notices worker starting work");
         }
         static int WorkerCompletedWork()
         {
        Console.WriteLine("Universe pleased with worker's work");
         return 7;
         }
         static void Main()
         {
         Worker peter = new Worker();
         Boss boss = new Boss();
        peter.completed += new WorkCompleted(boss.WorkCompleted); //【譯注:
        √】
        peter.started += new WorkStarted(Universe.WorkerStartedWork);
        peter.completed += new WorkCompleted(Universe.WorkerCompletedWork);
        peter.DoWork();
        Console.WriteLine("Main: worker completed work");
        Console.ReadLine();
         }
        }
        /*

        以下是上段程序輸出結(jié)果:
        Worker: work started
        Universe notices worker starting work
        Worker: work progressing
        Worker: work completed
        Better...// 【譯注:boss也通知到啦J“√”那一行代碼有用啦J,但是且慢,boss打
        的那4分沒有得到,后面只得到了Universe給的7分L】
        Universe pleased with worker's work
        Worker grade = 7
        Main: worker completed work
        */ <>

        溫馨提示:喜歡本站的話,請收藏一下本站!

        本類教程下載

        系統(tǒng)下載排行

        主站蜘蛛池模板: 日本免费福利视频| 美女视频黄a视频全免费网站一区| 97青青草原国产免费观看| 日本激情猛烈在线看免费观看 | 亚洲人成伊人成综合网久久| 亚洲高清国产AV拍精品青青草原| 麻豆精品国产免费观看| 成年女人18级毛片毛片免费观看| 国产综合免费精品久久久| eeuss影院www天堂免费| 久久久久久噜噜精品免费直播| 337p日本欧洲亚洲大胆人人| 亚洲熟女www一区二区三区| WWW国产亚洲精品久久麻豆| 老子影院午夜伦不卡亚洲| 免费看一级高潮毛片| 国产午夜成人免费看片无遮挡 | 国产免费不卡v片在线观看| 精品国产污污免费网站aⅴ| 99久久99久久精品免费看蜜桃 | 亚洲黄色免费网站| 成人免费福利视频| 国产男女猛烈无遮挡免费视频| 免费国产真实迷j在线观看| 国产亚洲av片在线观看播放| 久久精品国产亚洲AV无码偷窥| 亚洲欧洲国产综合| 国产黄色免费观看| 女人被男人桶得好爽免费视频| 亚洲A∨精品一区二区三区| 亚洲电影中文字幕| 亚洲av无码专区国产不乱码| 久久精品成人免费看| 免费看又爽又黄禁片视频1000| 久久久久一级精品亚洲国产成人综合AV区| 国产亚洲真人做受在线观看| 色偷偷女男人的天堂亚洲网| 国产大片免费天天看| 精品少妇人妻AV免费久久洗澡| 亚洲国产精品久久久久| 一本久久A久久免费精品不卡|