溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C#中委托的概念與使用方法是什么

發(fā)布時(shí)間:2023-02-27 14:16:26 來(lái)源:億速云 閱讀:296 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容主要講解“C#中委托的概念與使用方法是什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“C#中委托的概念與使用方法是什么”吧!

委托的概念

委托這個(gè)名字取的神乎其神的,但實(shí)質(zhì)是函數(shù)式編程,把函數(shù)作為參數(shù)傳遞給另一個(gè)參數(shù)。對(duì)于C語(yǔ)言程序員來(lái)說(shuō),就是把函數(shù)指針當(dāng)作參數(shù)傳遞給另一個(gè)函數(shù)。

唯一需要注意的是,C#畢竟是強(qiáng)類(lèi)型語(yǔ)言,用于委托的函數(shù),也相當(dāng)于變成了一種可以被傳遞的變量,所以在創(chuàng)建以及調(diào)用之前,需要聲明其數(shù)據(jù)類(lèi)型

delegate int Op(int a, int b);

這個(gè)委托是一種需要傳入兩個(gè)整型參數(shù)的函數(shù),返回值也是整數(shù)。接下來(lái)對(duì)這個(gè)委托進(jìn)行實(shí)例化,最終代碼如下

int add(int a, int b)
{
    return a + b;
}

var addTest = new Op(add);
void calc(Op func, int a, int b)
{
    Console.WriteLine($"func({a},)={func(a,b)}");
}

calc(addTest, 2, 3);
delegate int Op(int a, int b);

事先說(shuō)明一下,本文所有代碼均在.Net6的頂級(jí)語(yǔ)句中實(shí)現(xiàn),頂級(jí)語(yǔ)句需要把delegate聲明放在最下面。

其中,add是一個(gè)十分質(zhì)樸的函數(shù),沒(méi)什么可說(shuō)的;addTest是一個(gè)內(nèi)置了add了Op對(duì)象,其功能與add是相同的。

calc是一個(gè)以O(shè)p對(duì)象為參數(shù)的函數(shù),在這個(gè)函數(shù)中,通過(guò)Op對(duì)象func,計(jì)算了另外兩個(gè)參數(shù)a和b。

最后,調(diào)用了calc函數(shù),將addTest作為參數(shù),實(shí)質(zhì)上是計(jì)算了add(2,3),并打印了這個(gè)結(jié)果。

func(2,3)=5

>“調(diào)試停止時(shí)自動(dòng)關(guān)閉控制臺(tái)”。
按任意鍵關(guān)閉此窗口. . .

多播委托

所謂多播委托,就是一個(gè)委托中通過(guò)+=運(yùn)算符添加多個(gè)函數(shù)。當(dāng)然也可以通過(guò)-=運(yùn)算符將原本添加的函數(shù)刪除掉。

為了演示這個(gè)功能,將上述代碼稍作更改。

int add(int a, int b){
    Console.WriteLine($"{a}+={a+b}");
    return a + b;
}

int minus(int a, int b){
    Console.WriteLine($"{a}-={a-b}");
    return a-b;
}

void calc(Op func, int a, int b)
{
    func(a,b);
}

Op opTest = add;
opTest += minus;
opTest += add;
opTest += minus;
calc(opTest, 3, 4);
Console.WriteLine("減去一個(gè)minus");
opTest -= minus;
calc(opTest, 3, 4);

delegate int Op(int a, int b);

其中Op opTest=add的寫(xiě)法等價(jià)于Op opTest = new OpTest(add),但若省略new,則不可寫(xiě)為var opTest = add,這個(gè)時(shí)候沒(méi)法進(jìn)行類(lèi)型推斷。

輸出結(jié)果為

3+4=7
3-4=-1
3+4=7
3-4=-1
減去一個(gè)minus
3+4=7
3-4=-1
3+4=7

由此可知,委托在調(diào)用的時(shí)候,會(huì)按照+=的先后順序調(diào)用函數(shù),并將最后一個(gè)調(diào)用的函數(shù)作為返回值。

而函數(shù)在委托中以棧的方式存放,-=會(huì)先減去后存入委托中的函數(shù)。

拖動(dòng)按鈕

多播委托在GUI編程中最為常用,尤其是拖動(dòng)控件時(shí)。拖動(dòng)控件的流程包括三個(gè)步驟

  • 鼠標(biāo)點(diǎn)擊控件

  • 鼠標(biāo)拖動(dòng)控件

  • 鼠標(biāo)松開(kāi)控件

則對(duì)于一個(gè)控件來(lái)說(shuō),其綁定的事件會(huì)隨著鼠標(biāo)的點(diǎn)擊情況而發(fā)生變化

0. 鼠標(biāo)未點(diǎn)擊時(shí),控件需要響應(yīng)鼠標(biāo)點(diǎn)擊事件

  • 鼠標(biāo)點(diǎn)擊之后,控件需要響應(yīng)鼠標(biāo)拖動(dòng)、鼠標(biāo)松開(kāi)的事件

  • 鼠標(biāo)拖動(dòng)時(shí),控件響應(yīng)的事件并不發(fā)生變化

  • 鼠標(biāo)松開(kāi)后,控件需要解綁拖動(dòng)以及松開(kāi)事件

接下來(lái),實(shí)操一下,簡(jiǎn)單起見(jiàn),GUI采用winForm,在新建項(xiàng)目之后,拖動(dòng)一個(gè)按鈕到窗口上,右鍵按鈕->屬性,可以更改一下名字和內(nèi)容,然后點(diǎn)擊右下角屬性

欄的小閃電,然后注冊(cè)MouseDown事件,輸入btnTest_MouseDown并按下回車(chē)之后,IDE會(huì)自動(dòng)來(lái)到代碼界面,并出現(xiàn)一個(gè)空的委托函數(shù)。

private void btnTest_MouseDown(object sender, MouseEventArgs e)
{

}

為了理解這個(gè)東西的作用,可以在解決方案資源管理器中找到Form1.Designer.cs文件,點(diǎn)進(jìn)去之后可以看到下面這行代碼

this.btnTest.MouseDown += new System.Windows.Forms.MouseEventHandler(this.btnTest_MouseDown);

換言之,btnTest.MouseDown就是一個(gè)多播委托,剛剛我們的行為,為其注冊(cè)了一個(gè)名為btnTest_MouseDown的實(shí)現(xiàn),盡管這個(gè)實(shí)現(xiàn)現(xiàn)在還是空的。

若想拖動(dòng)一個(gè)控件,第一步就是按下鼠標(biāo),按下鼠標(biāo)之后,需要再注冊(cè)兩個(gè)委托,分別再拖動(dòng)鼠標(biāo)和松開(kāi)鼠標(biāo)時(shí)起作用;而松開(kāi)鼠標(biāo)和按下鼠標(biāo)的作用剛好相反,要求取消注冊(cè)拖動(dòng)事件,所以下面分別實(shí)現(xiàn)這三個(gè)功能。

private void btnTest_MouseDown(object sender, MouseEventArgs e)
{
   btnTest.MouseMove += btnTest_MouseMove;
   btnTest.MouseLeave += btnTest_MouseLeave;
}
private void btnTest_MouseLeave(object sender, EventArgs e)
{
   btnTest.MouseMove -= btnTest_MouseMove;
   btnTest.MouseLeave -= btnTest_MouseLeave;
}
private void btnTest_MouseMove(object sender, MouseEventArgs e)
{
   int dh = btnTest.Height / 2;
   int dw = btnTest.Width / 2;
   btnTest.Top = MousePosition.Y - this.Top - dh;
   btnTest.Left = MousePosition.X - this.Left - dw;
}

上面需要注意一點(diǎn),MouseLeave和MouseMove, MoseDown是不同類(lèi)型的委托,故而創(chuàng)建函數(shù)的參數(shù)類(lèi)型是不同的。

btnTest.Top為按鈕頂端距離窗口頂端的距離;MousePosition.Y表示鼠標(biāo)距離屏幕頂端的距離;this.Top表示窗口頂端距離屏幕頂端的位置,最后再減去一個(gè)按鈕高度的一半,相當(dāng)于是把按鈕的中心移動(dòng)到鼠標(biāo)光標(biāo)處。這種邏輯過(guò)于簡(jiǎn)單粗暴,實(shí)際工作時(shí)不會(huì)用到,之所以這么寫(xiě)是因?yàn)楹?jiǎn)單。

效果如下

C#中委托的概念與使用方法是什么

到此,相信大家對(duì)“C#中委托的概念與使用方法是什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI