最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

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

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

委托的使用案例

定義委托和方法

        //委托定義(要與方法中參數(shù)一致)
        public delegate int DelegateTest(int n1, int n2);
 
        class Math
        {
            //方法定義(委托要執(zhí)行的方法,本案例把方案寫(xiě)到class類(lèi)中)
            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)起來(lái) (委托:將方法當(dāng)作另一個(gè)方法的參數(shù)來(lái)進(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");
 
            //****委托的另外一寫(xiě)法,通過(guò)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();
            //委托的另外一寫(xiě)法,通過(guò)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();
 
            //訂閱事件(類(lèi)似于 方法與委托事件的關(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)鴻門(mén)宴,吩咐部下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開(kāi)始**";
            }
 
            //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開(kāi)始**";
            }
 
            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í)際開(kāi)發(fā)中,下面這個(gè)類(lèi)會(huì)封裝起來(lái),只提供函數(shù)接口。相當(dāng)于系統(tǒng)底層

        //實(shí)際開(kāi)發(fā)中,下面這個(gè)類(lèi)會(huì)封裝起來(lái),只提供函數(shù)接口。相當(dāng)于系統(tǒng)底層
        class CalculateClass
        {
            public delegate int SomeCalculateWay(int num1, int num2);
            //將傳入?yún)?shù)在系統(tǒng)底層進(jìn)行某種處理,具體計(jì)算方法由開(kāi)發(fā)者開(kāi)發(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);
            }
        }

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

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

用戶(hù)層,執(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");
        }

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

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

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

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

相關(guān)文章

最新評(píng)論

永和县| 佳木斯市| 周至县| 昭苏县| 新沂市| 洛南县| 伊春市| 新宁县| 阳曲县| 江西省| 牟定县| 宁明县| 永川市| 宣威市| 治县。| 偏关县| 襄樊市| 唐山市| 临武县| 南充市| 甘南县| 九江县| 莆田市| 万州区| 郑州市| 华池县| 吕梁市| 呼图壁县| 鄂托克前旗| 海淀区| 含山县| 芦山县| 齐齐哈尔市| 修武县| 进贤县| 崇礼县| 英吉沙县| 延长县| 绥宁县| 南涧| 保山市|