欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C#中委托、事件和回調(diào)的使用及說明

 更新時(shí)間:2022年09月09日 14:08:35   作者:云無極  
這篇文章主要介紹了C#中委托、事件和回調(diào)的使用及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

委托是一個(gè)類,它定義了方法的類型,使得可以將方法當(dāng)作另一個(gè)方法的參數(shù)來進(jìn)行傳遞,這種將方法動(dòng)態(tài)地賦給參數(shù)的做法,可以避免在程序中大量使用If-Else(Switch)語句,同時(shí)使得程序具有更好的可擴(kuò)展性。

事件是對(duì)委托的封裝。如果不進(jìn)行封裝,讓委托暴露給調(diào)用者,調(diào)用者就可以把委托變量重新引用到新的委托對(duì)象,也就刪除了當(dāng)前要調(diào)用的方法列表;

定義一個(gè)事件有兩步,首先定義一個(gè)委托,它包括了這件事的“協(xié)議”和委托方法(由誰去做);其次,用event關(guān)鍵字和相關(guān)委托聲明這個(gè)事件。事件像是一個(gè)接口,封裝了委托所定的“協(xié)議”。由于委托已經(jīng)定義了協(xié)議,剩下的就是按這個(gè)協(xié)議去辦事,至于怎么做它并不關(guān)心。調(diào)用者無法訪問委托對(duì)象。

回調(diào)函數(shù)就是把一個(gè)方法的傳給另外一個(gè)方法去執(zhí)行。回調(diào)函數(shù)只是一個(gè)功能片段,由用戶按照回調(diào)函數(shù)的調(diào)用約定來實(shí)現(xiàn)的一個(gè)函數(shù)??梢园讶我庖粋€(gè)符合這個(gè)委托的方法傳遞進(jìn)去,意思就是說這部分代碼是可變的。而設(shè)計(jì)上有一個(gè)抽離出可變部分代碼的原則,這種用法無疑可以用到那種場(chǎng)合了。從上可知,事件和回調(diào)都是對(duì)委托的一種用法。事件是把委托封裝起來,而回調(diào)函數(shù)則是由委托綁定不同的函數(shù)來實(shí)現(xiàn)不同的功能。

委托的使用案例

定義委托和方法

        //委托定義(要與方法中參數(shù)一致)
        public delegate int DelegateTest(int n1, int n2);
 
        class Math
        {
            //方法定義(委托要執(zhí)行的方法,本案例把方案寫到class類中)
            public int Multiply(int n1, int n2)
            {
                return n1 * n2;
            }
 
            public int AddTest(int n1, int n2)
            {
                return n1 + n2;
            }
        }

委托的使用

        private void button1_Click(object sender, EventArgs e)
        {
            Math objMath = new Math();
 
            //創(chuàng)建委托對(duì)象
            DelegateTest delegateDemo1;
 
            //將方法與委托對(duì)象關(guān)聯(lián)起來 (委托:將方法當(dāng)作另一個(gè)方法的參數(shù)來進(jìn)行傳遞)
            //delegateDemo1 = new CallDelegate(objMath.Multiply);
            delegateDemo1 = objMath.Multiply; //與上面方法相同
            //delegateDemo1 += objMath.AddTest;  //給委托對(duì)象再綁定一個(gè)方法,若該條代碼執(zhí)行,顯示結(jié)果為17
 
            //將委托實(shí)例化
            int result = delegateDemo1(5, 12);
            richTextBox1.AppendText(result.ToString() + "\r");
 
            //****委托的另外一寫法,通過Action或Func,如果有返回值用Func,否則用Action *****//
            //Func<int, int, int> func1 = new Func<int, int, int>(objMath.Multiply);
            Func<int, int, int> func1 = objMath.Multiply;
            richTextBox1.AppendText(func1.Invoke(6, 13) + "\r");
        }

執(zhí)行的結(jié)果

利用Action或Func簡(jiǎn)化代碼

        private void button4_Click(object sender, EventArgs e)
        {
            Math objMath = new Math();
            //委托的另外一寫法,通過Action或Func,如果有返回值用Func,否則用Action
            //Func<int, int, int> func1 = new Func<int, int, int>(objMath.Multiply); //同下
            Func<int, int, int> func1 = objMath.Multiply;
            richTextBox1.AppendText(func1.Invoke(6, 13) + "\r");
        }

事件的使用案例

        class ClassA
        {
            public string ClassAinfo = "A 默認(rèn)!";
            public void DispInfo()
            {
                ClassAinfo = "A 收到!";
            }
        }
 
        class ClassB
        {
            public string ClassAinfo = "B 默認(rèn)!";
            public void DispInfo()
            {
                ClassAinfo = "B 收到!";
            }
        }
        class DelegatEventTest
        {
            //定義委托
            public delegate void MyDelegateEventHandler();
            //定義事件
            public event MyDelegateEventHandler NotifyEveryOne;
            //調(diào)用事件
            public void Notify()
            {
                if (NotifyEveryOne != null)
                {
                    NotifyEveryOne();
                }
            }
        }

事件的使用

        private void button3_Click(object sender, EventArgs e)
        {
            //創(chuàng)建classA和classB的對(duì)象
            ClassA objA = new ClassA();
            ClassB objB = new ClassB();
            //創(chuàng)建委托的對(duì)象
            DelegatEventTest event1 = new DelegatEventTest();
 
            //訂閱事件(類似于 方法與委托事件的關(guān)聯(lián))
            event1.NotifyEveryOne += new DelegatEventTest.MyDelegateEventHandler(objA.DispInfo);
            //event1.NotifyEveryOne += new DelegatEventTest.MyDelegateEventHandler(objB.DispInfo);
 
            event1.Notify();
 
            richTextBox1.AppendText(objA.ClassAinfo + "\r");
            richTextBox1.AppendText(objB.ClassAinfo + "\r");
        }

帶參數(shù)的事件案例

參考網(wǎng)上的案例,場(chǎng)景:首領(lǐng)boyK要搞一場(chǎng)鴻門宴,吩咐部下boyA和boyB各自帶隊(duì)埋伏在屏風(fēng)兩側(cè),約定以杯為令:若左手舉杯,則boyA帶隊(duì)殺出;若右手舉杯,則boyB帶隊(duì)殺出;若直接摔杯,則boyA和boyB同時(shí)殺出。boyA和boyB襲擊的具體方法,首領(lǐng)boyK并不關(guān)心。

boyK的定義

        public class BoyK
        {
            //定義委托
            public delegate void RaiseEventHandler(string hand);
            public delegate void FallEventHandler();
 
            //定義事件
            public event RaiseEventHandler RaiseEvent;
            public event FallEventHandler FallEvent;
 
            //調(diào)用事件(例:舉手事件)
            public void Raise(string hand)
            {
                if (RaiseEvent!=null)
                {
                    RaiseEvent(hand);
                }
            }
            //調(diào)用事件(例:摔杯事件)
            public void Fall()
            {
                if (FallEvent!=null)
                {
                    FallEvent();
                }
            }            
        }

boyA的定義

        class BoyA
        {
            public string str = "A待命";
            BoyK boyk;
            public BoyA(BoyK k)
            {
                boyk = k;
                k.RaiseEvent += new BoyK.RaiseEventHandler(k_RaiseEvent);   //訂閱舉杯事件
                k.FallEvent += new BoyK.FallEventHandler(k_FallEvent);      //訂閱摔杯事件
            }
            public void Attack()
            {
                str = "A開始**";
            }
 
            //boyK舉杯的動(dòng)作
            void k_RaiseEvent(string hand)
            {
                if (hand.Equals("左"))
                {
                    Attack();
                }
            }
 
            void k_FallEvent()
            {
                Attack();
            }         
        }

boyB的定義

        class BoyB
        {
            public string str = "B待命";
            BoyK boyk;
            public BoyB(BoyK k)
            {
                boyk = k;
                k.RaiseEvent += new BoyK.RaiseEventHandler(k_RaiseEvent);   //訂閱舉杯事件
                k.FallEvent += new BoyK.FallEventHandler(k_FallEvent);      //訂閱摔杯事件
            }
 
            public void Attack()
            {
                str = "B開始**";
            }
 
            void k_RaiseEvent(string hand)
            {
                if (hand.Equals("右"))
                {
                    Attack();
                }
            }
 
            void k_FallEvent()
            {
                Attack();
            }
        }

事件的使用

        private void button2_Click(object sender, EventArgs e)
        {
            BoyK boyK = new BoyK();
            BoyA boyA = new BoyA(boyK);
            BoyB boyB = new BoyB(boyK);
 
            //boyK.Raise("左");
            boyK.Raise("右");
            //boyK.Fall();
 
            richTextBox1.AppendText(boyA.str+"\r");
            richTextBox1.AppendText(boyB.str + "\r");
        }

運(yùn)行效果

回調(diào)函數(shù)的使用案例

實(shí)際開發(fā)中,下面這個(gè)類會(huì)封裝起來,只提供函數(shù)接口。相當(dāng)于系統(tǒng)底層

        //實(shí)際開發(fā)中,下面這個(gè)類會(huì)封裝起來,只提供函數(shù)接口。相當(dāng)于系統(tǒng)底層
        class CalculateClass
        {
            public delegate int SomeCalculateWay(int num1, int num2);
            //將傳入?yún)?shù)在系統(tǒng)底層進(jìn)行某種處理,具體計(jì)算方法由開發(fā)者開發(fā),函數(shù)僅提供執(zhí)行計(jì)算方法后的返回值
            //下面的代碼中相當(dāng)于調(diào)用了一個(gè)回調(diào)函數(shù)
            public int Calculate(int num1, int num2, SomeCalculateWay call)
            {
                return call(num1, num2);
            }
        }

開發(fā)層處理,開發(fā)人員編寫具體的計(jì)算方法

        //開發(fā)層處理,開發(fā)人員編寫具體的計(jì)算方法
        class FunctionClass
        {
            public int GetSum(int a, int b)
            {
                return a + b;
            }
 
            public int GetMulti(int a, int b)
            {
                return a * b;
            }
        }

用戶層,執(zhí)行輸入等操作

        private void button4_Click(object sender, EventArgs e)
        {
            CalculateClass cc = new CalculateClass();
            FunctionClass fc = new FunctionClass();
 
            int result1 = cc.Calculate(2, 3, fc.GetSum);
            int result2 = cc.Calculate(2, 3, fc.GetMulti);
 
            richTextBox1.AppendText(result1 + "\r");
            richTextBox1.AppendText(result2 + "\r");
        }

說明:上述代碼中的FunctionClass中的GetSum()和GetMulti()兩個(gè)函數(shù)稱為回調(diào)函數(shù)。

可以看到整個(gè)程序中并沒有哪個(gè)地方通過類似GetSum(1,2)這種形式調(diào)用了該函數(shù),只有將其當(dāng)作另一個(gè)函數(shù)的參數(shù)來進(jìn)行調(diào)用。

如cc.PrintAndCalculate(2, 3, fc.GetSum)。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。 

相關(guān)文章

  • Unity3D手機(jī)陀螺儀的使用方法

    Unity3D手機(jī)陀螺儀的使用方法

    這篇文章主要為大家詳細(xì)介紹了Unity3D手機(jī)陀螺儀的使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • C#獲取系統(tǒng)當(dāng)前IE版本號(hào)

    C#獲取系統(tǒng)當(dāng)前IE版本號(hào)

    這篇文章主要為大家詳細(xì)介紹了C#獲取系統(tǒng)當(dāng)前IE版本號(hào),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C#遞歸方法實(shí)現(xiàn)無限級(jí)分類顯示效果實(shí)例

    C#遞歸方法實(shí)現(xiàn)無限級(jí)分類顯示效果實(shí)例

    這篇文章主要介紹了C#遞歸方法實(shí)現(xiàn)無限級(jí)分類顯示效果,結(jié)合完整實(shí)例形式分析了C#遞歸算法與數(shù)據(jù)元素遍歷的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • C#模擬實(shí)現(xiàn)鼠標(biāo)自動(dòng)點(diǎn)擊與消息發(fā)送功能

    C#模擬實(shí)現(xiàn)鼠標(biāo)自動(dòng)點(diǎn)擊與消息發(fā)送功能

    這篇文章主要為大家詳細(xì)介紹了C#如何利用windows api來模擬實(shí)現(xiàn)鼠標(biāo)點(diǎn)擊、右擊、雙擊以及發(fā)送文本功能,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2022-08-08
  • C#實(shí)現(xiàn)發(fā)送郵件的方法

    C#實(shí)現(xiàn)發(fā)送郵件的方法

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)發(fā)送郵件的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • C#中IsNullOrEmpty和IsNullOrWhiteSpace的使用方法及區(qū)別解析

    C#中IsNullOrEmpty和IsNullOrWhiteSpace的使用方法及區(qū)別解析

    今天我們將探討C#中兩個(gè)常用的字符串處理方法:IsNullOrEmpty和IsNullOrWhiteSpace,本文中,我們將詳細(xì)解釋這兩個(gè)方法的功能和使用場(chǎng)景,并幫助您更好地理解它們之間的區(qū)別,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧
    2023-07-07
  • C#定時(shí)器和隨機(jī)數(shù)

    C#定時(shí)器和隨機(jī)數(shù)

    在前一篇中我們介紹了鍵盤和鼠標(biāo)事件,其實(shí)還有一個(gè)非常常用的事件,就是定時(shí)器事件,如果要對(duì)程序?qū)崿F(xiàn)時(shí)間上的控制,那么就要使用到定時(shí)器。而隨機(jī)數(shù)也是很常用的一個(gè)功能,在我們要想產(chǎn)生一個(gè)隨機(jī)的結(jié)果時(shí)就要使用到隨機(jī)數(shù)。本文我們就來簡(jiǎn)單介紹一下定時(shí)器和隨機(jī)數(shù)。
    2015-06-06
  • C#語言主要特性總結(jié)

    C#語言主要特性總結(jié)

    這篇文章主要介紹了C#語言主要特性總結(jié),本文總結(jié)了C#語言的簡(jiǎn)單、現(xiàn)代、面向?qū)ο?、類型安全、相互兼容性、可伸縮性和可升級(jí)性等幾個(gè)主要特點(diǎn),需要的朋友可以參考下
    2015-02-02
  • C#?try?catch?使用實(shí)例詳解

    C#?try?catch?使用實(shí)例詳解

    在編程中,?try-catch-throw?是一種常見的錯(cuò)誤處理模式,這三個(gè)關(guān)鍵字通常一起使用,以捕獲異常、處理異常和重新拋出異常,這篇文章主要介紹了C#?try?catch?使用,需要的朋友可以參考下
    2023-09-09
  • C#怎樣實(shí)現(xiàn)文件下載斷點(diǎn)續(xù)傳

    C#怎樣實(shí)現(xiàn)文件下載斷點(diǎn)續(xù)傳

    這篇文章主要介紹了C#怎樣實(shí)現(xiàn)文件下載斷點(diǎn)續(xù)傳,對(duì)斷點(diǎn)續(xù)傳感興趣的同學(xué),可以參考下
    2021-04-04

最新評(píng)論